Сначала KISS: решаем, требуется ли делать код сложным или можно обойтись простым решением, которое будет легко читать и поддерживать.
Если понятно, что читать и поддерживать простыню процедурщины будет затруднительно, начинаем дробить логику, и в этом нам помогает SOLID - именно он определяет границы зон ответственности кода и позволяет минимизировать связи между проектируемыми классами.
Наконец, определившись с архитектурой, мы внутри каждого класса вновь возвращаемся к KISS, не переусложняя его внутреннюю жизнь сверх тех задач, что он должен решать. Благодаря применению SOLID уровнем выше мы сможем безболезненно переделать все потроха этого класса, если задачи изменятся и KISS-решение перестанет работать, без рефакторинга остального кода.
Никаких противоречий.