Про SOLID множество статей, но они длины и не рассматривают практические плюсы\минусы. Часть команд относится к SOLID как к "священной корове", расплачиваясь сроками реализации и недовольством бизнеса. Поэтому описал принципы SOLID кратко, с плюсами и минусами. Приятного чтения!

⚠️Принципы SOLID

1.     S: Принцип единственности ответственности (The Single Responsibility Principle)

Один класс — одна ответственность

→ Класс должен иметь только одну причину для изменения.

→ Пример: Класс User должен управлять данными пользователя, а отправкой писем — другой класс.

Зачем: Понять за что отвечает класс, что от него ждать. Легче чинить и менять без побочных эффектов.

? Реализация: Каждый класс имеет краткое ясное описание.

2.     O: Принцип открытости/закрытости (The Open Closed Principle)

Расширяй, но не переделывай

→ Добавляй новую функциональность через новые классы/методы не меняя старые.

→ Пример: Вместо правки класса Report создай PDFReport и ExcelReport.

Зачем: Внесение изменений в существующий код – риски поломать зависимый код. При соблюдении принципа старый код остается неизменным, новое — не ломает старое.

? Реализация: Инъекции зависимостей, полиморфизм, наследование, делегаты, события и т.д.

3.     L: Принцип замещения Лисков (The Liskov Substitution Principle)

Лисков – это имя собственное, фамилия Барбары Лиско. Ученной из Америки. Барбара сформулировала данный принцип.

→ Дочерние классы должны соблюдать требования к родителю.
→ Пример: Если Утка умеет летать, то РезиноваяУтка не должна выбрасывать ошибку при полете.

Зачем: Можно смело использовать наследников везде, где работает родитель.

? Реализация: Проверка соблюдения требований (контракта на класс), через кодеревью, покрытие поведения наследников тестами.

4.     I: Принцип разделения интерфейса (The Interface Segregation Principle)

Интерфейсы — как меню: отлично, когда содержат только то, что нужно.

→ Дели большие интерфейсы на маленькие и специализированные.
→ Пример: Вместо IMegaPrinter сделай IPrinter + IScanner.
Зачем: Клиенты не должны зависеть от методов, которые они не используют. Простой интерфейс быстрее понять.

? Реализация: проверка, что методы интерфейса объедены одной логикой и используются вместе.

5.     D: Принцип инверсии зависимости (The Dependency Inversion Principle)

Зависеть от абстракций, а не от конкретных реализаций

→ Классы должны работать с интерфейсами, а не с конкретными реализациями.
→ Пример: OrderService зависит от интерфейса IPaymentProcessor, а не от класса PayPalPayment.

Зачем: Легко менять реализации (например, перейти с PayPal на Stripe).

? Реализация: паттерны Стратегия, Состояние; передача инъекций через конструктор, свойство; передача лямбд и делегатов.

Главная цель SOLID:

Код, которой легко чинить, улучшать и тестировать в команде.

SOLID помогает снизить риски поломать то, что есть и вероятность конфликтов одновременного изменения одного участка кода несколькими разработчиками.

⚠️Минусы соблюдения SOLID

1.     Сложность и избыточность

→ Множество мелких классов/интерфейсов усложняют навигацию по коду.

→ Пример: Вместо одного класса OrderProcessor появляются IOrderValidator, IPaymentService, IShippingCalculator + их реализации.

→ Итог: Код превращается в «лего» с сотнями файлов — новичкам трудно разобраться.

2.     Преждевременная оптимизация

→ Попытки «предусмотреть всё» ведут к переусложнению.

→ Пример: Создание интерфейса IReportExporter для единственной реализации PDFExporter.
→ Философия: «Не создавай абстракцию, пока нет реальной необходимости» (YAGNI+KISS > SOLID).

3.     Падение производительности

→ Цепочки абстракций (особенно DI) создают накладные расходы.
→ Пример: множество уровней вызовов через интерфейсы замедляют работу в high-load системах.

4.     Антипаттерн «Интерфейс на каждый чих»

→ Чрезмерное дробление интерфейсов (I-принцип) приводит к «интерфейсному взрыву».

→ Пример: 10 интерфейсов для сервиса пользователя (IUserReader, IUserWriter, IUserDeleter...).

5.     Проблемы наследования (LSP)

→ Жёсткое требование «подстановки Лисков» иногда противоречит бизнес-логике или скорости получения MVP.

→ Пример: Класс Penguin не может быть подтипом Bird, если у птицы есть метод fly().

? Когда SOLID вредит:

  • Прототипы и MVP — замедляет разработку.

  • Маленькие проекты — избыточная абстракция не окупается.

  • High-performance код (например, game dev) — накладные расходы DI/интерфейсов критичны.

⚖️ SOLID — не догма, а инструмент. Применяйте его там, где он дает выгоду:

✅ В долгоживущих проектах

✅ В командах от 3+ разработчиков

✅ Для компонентов с высокой частотой изменений

✅ Как способ упростить код для дальнейшего развития

? Как избежать проблем:

1.     Рефакторить постепенно — не пытайтесь «сделать идеально» сразу.

2.     Измерять оверхеад — профилируйте код после внедрения абстракций.

3.     Нарушать осознанно — если SOLID противоречит здравому смыслу, ищите компромисс.

4.     Использовать YAGNI («You Ain’t Gonna Need It») — не добавляйте абстракции «на будущее».

Итог

SOLID — отличная профилактика для:

✅ поддержания порядка;

✅ снижения вероятности конфликтов правок одного участка кода;

✅ разделение зон ответственности интерфейсов, классов;

✅ упрощения внесения изменений без рисков поломать проект.

Фанатичное применение SOLID превращает проект в «в перегруженный балласт», где даже простое изменение требует изменений в 20 файлах, а многие классы, интерфейсы пустая трата времени и денег без которой код работал бы так же. Здравый смысл — главное оружие разработчика. ?️

Что почитать

Принципы проектирования классов (S.O.L.I.D.)

Глава «The Single Responsibility Principle» из книги Роберта Мартина «Agile Principles, Patterns, and Practices in C#»

InfoQ: Making Roles Explicit

R. Martin: The Open-Closed Principle

P&P: The Open Closed Principle

LosTechies: The Open Closed Principle

R. Martin: The Liskov Substitution Principle

LosTechies: The Liskov Substitution Principle

Wikipedia: Liskov substitution principle

Роберт Мартин: The Interface Segregation Principle

LosTechies: The Interface Segregation Principle

Роберт Мартин: The Dependency Inversion Principle

James Kovacs: Tame Your Software Dependencies for More Flexible Apps

Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern

Wikipedia: Dependency injection

Готовлю на мидл+/сеньора. Собираю материал для подготовки к собеседованию и делаю простым для понимания. Хочу сделать цикл статей, если у вас есть темы трудные для понимания — пишите, по возможности помогу.

P.S. Текст отформатирован с помощью ИИ. Нравятся как он расставляет эмодзи, с ними проще читать.

Комментарии (12)


  1. bromzh
    11.08.2025 10:54

    Если не хотите палиться, что статья - просто копипаста с нейронки - удаляйте эмодзи.

    Хочу сделать цикл статей

    Тоже нейропаста?


  1. Lewigh
    11.08.2025 10:54

    Класс должен решать только одну проблему.

    Пусть будет так. Для того чтобы это сделать нужно правило - как детерминировано определить какую единственную задачу должен решать класс. Где это правило?

    Добавляй новую функциональность через новые классы/методы не меняя старые.

    А если нужно поменять старые?

    Дочерние классы должны соблюдать требования к родителю.

    В оригинальном принципе нет ни слова про классы.

    Дели большие интерфейсы на маленькие и специализированные.

    Пусть будет так. А где правило согласно которого мы определяем что такое большие а что такое маленькие интерфейсы? Без этого правила принцип - это красивый и бесполезный набор слов.

     Преждевременная оптимизация

    → Попытки «предусмотреть всё» ведут к переусложнению.

    → Пример: Создание интерфейса IReportExporter для единственной реализации PDFExporter.
    → Философия: «Не создавай абстракцию, пока нет реальной необходимости» (YAGNI+KISS > SOLID).

    Причем здесь оптимизация? Оптимизация, в нашем контексте - это сокращение потребления ресурсов без потери функциональности, например процессора и памяти. Какое к этому имеют отношение создание каких то интерфейсов?

    В сухом остатке так и не понятно из статьи. Есть абстрактный SOLID который непонятно как использовать а если использовать то еще и куча проблем может быть и нужно 10 раз подумать. А по итогу то нужно или нет? Если нужно то где обоснование что оно имеет больше плюсов чем минусов?

    PS Статья написана нейронкой а ответы хотелось бы от автора получить.


    1. herodream Автор
      11.08.2025 10:54

      Интересные вопросы. Предлагаю разделить их на отдельные треды, чтоб можно было точно понимать, что обсуждаем. Также сегодня уезжаю на неделю в горы, буду отвечать по мере возможностей.