Что такое принципы SOLID в объектно-ориентированном программировании?

«Что такое принципы SOLID в объектно-ориентированном программировании?» — вопрос из категории ООП, который задают на 43% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

SOLID — это пять основных принципов проектирования, которые делают код более гибким, понятным и поддерживаемым.

  1. S — Принцип единственной ответственности (Single Responsibility): Класс должен иметь только одну причину для изменения.

    // Плохо: Класс занимается и бизнес-логикой, и логированием.
    class UserService {
        void saveUser(User u) { /*...*/ }
        void logToFile(String msg) { /*...*/ } // Нарушение SRP
    }
    // Хорошо: Ответственность разделена.
    class UserService { void saveUser(User u) { /*...*/ } }
    class Logger { void log(String msg) { /*...*/ } }
  2. O — Принцип открытости/закрытости (Open/Closed): Классы должны быть открыты для расширения, но закрыты для модификации.

    interface Shape { double area(); }
    class Circle implements Shape { /*...*/ } // Новые фигуры добавляются без изменения существующего кода.
    class Square implements Shape { /*...*/ }
  3. L — Принцип подстановки Барбары Лисков (Liskov Substitution): Объекты подклассов должны быть заменяемы объектами родительского класса без изменения корректности программы.

  4. I — Принцип разделения интерфейса (Interface Segregation): Много специализированных интерфейсов лучше, чем один универсальный.

    // Плохо: Принтер вынужден реализовывать ненужный метод scan().
    interface MultiFunctionDevice { void print(); void scan(); }
    // Хорошо:
    interface Printer { void print(); }
    interface Scanner { void scan(); }
  5. D — Принцип инверсии зависимостей (Dependency Inversion): Зависимости должны строиться на абстракциях, а не на конкретных реализациях.

    // Зависим от абстракции (интерфейса), а не от конкретного класса.
    class OrderProcessor {
        private final PaymentGateway gateway; // PaymentGateway - интерфейс
        OrderProcessor(PaymentGateway gateway) { this.gateway = gateway; }
    }