Встречается на 40% собеседований по PHP

Что такое SOLID

SOLID — это акроним пяти принципов объектно-ориентированного проектирования, сформулированных Робертом Мартином (дядюшкой Бобом). Эти принципы помогают создавать гибкий, понятный и легко поддерживаемый код, упрощают тестирование и рефакторинг. На собеседовании важно не только перечислить принципы, но и показать понимание их практического применения.

Пять принципов SOLID

S — Single Responsibility Principle (Принцип единственной ответственности)

Класс должен иметь только одну причину для изменения, то есть отвечать за одну задачу или область ответственности. Например, класс Order не должен одновременно заниматься вычислением стоимости, сохранением в базу и отправкой email — лучше разделить эти обязанности на отдельные классы.

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

Программные сущности (классы, модули, функции) должны быть открыты для расширения, но закрыты для модификации. Новую функциональность следует добавлять через наследование, интерфейсы или композицию, не изменяя существующий код. Например, вместо правки класса PaymentProcessor для каждого нового способа оплаты, создайте интерфейс PaymentMethod и добавляйте новые реализации.

L — Liskov Substitution Principle (Принцип подстановки Барбары Лисков)

Объекты подклассов должны быть взаимозаменяемы с объектами родительского класса без нарушения работы программы. Если класс Bird имеет метод fly(), а подкласс Penguin не умеет летать, то это нарушение принципа — лучше вынести летающих птиц в отдельный интерфейс Flyable.

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

Клиенты не должны зависеть от методов, которые они не используют. Вместо одного «толстого» интерфейса лучше создавать несколько узкоспециализированных. Например, интерфейс Worker с методами work() и eat() заставляет робота реализовывать eat(), что не нужно. Разделите на Workable и Eatable.

D — Dependency Inversion Principle (Принцип инверсии зависимостей)

Модули верхнего уровня не должны зависеть от модулей нижнего уровня; оба должны зависеть от абстракций. Абстракции не должны зависеть от деталей; детали должны зависеть от абстракций. Это достигается через внедрение зависимостей (DI) и использование интерфейсов. Например, класс ReportGenerator должен зависеть от интерфейса ReportFormatter, а не от конкретного класса PdfFormatter.

Пример на PHP

Рассмотрим нарушение принципов и их исправление на простом примере.

Нарушение SRP и DIP:

php
class OrderService {
    public function createOrder($data) {
        // валидация, расчёт, сохранение, отправка email
    }
}

Рефакторинг с учётом SOLID:

php
interface OrderRepositoryInterface {
    public function save(Order $order): void;
}

class OrderRepository implements OrderRepositoryInterface {
    public function save(Order $order): void {
        // сохранение в БД
    }
}

class OrderService {
    public function __construct(
        private OrderRepositoryInterface $repository,
        private MailerInterface $mailer
    ) {}

    public function createOrder(array $data): Order {
        $order = new Order($data);
        $this->repository->save($order);
        $this->mailer->sendConfirmation($order);
        return $order;
    }
}

Здесь OrderService отвечает только за создание заказа, а зависимости (репозиторий, почтовик) внедряются через интерфейсы.

Подводные камни и частые ошибки

  • Переусложнение: слепое следование SOLID может привести к излишней абстракции и множеству мелких классов. Применяйте принципы разумно, особенно в небольших проектах.
  • Нарушение LSP: часто встречается, когда подкласс выбрасывает исключения или меняет контракт родителя. Проверяйте, что наследники действительно могут заменить родителя.
  • Интерфейсы-«зомби»: создание интерфейсов, которые никто не реализует, или методов, которые не используются. Это нарушает ISP.
  • Путаница между DIP и DI: DIP — это принцип проектирования, а DI (внедрение зависимостей) — один из способов его реализации. Не сводите DIP только к использованию контейнера.

Когда использовать SOLID

Принципы SOLID полезны при проектировании средних и крупных систем, где важны расширяемость и поддерживаемость. Для небольших скриптов или прототипов они могут быть избыточны. На собеседовании покажите, что понимаете, когда принципы уместны, а когда нет.

Коротко

  • SOLID — пять принципов ООП: единственная ответственность, открытость/закрытость, подстановка Лисков, разделение интерфейса, инверсия зависимостей.
  • Цель — гибкий, тестируемый и поддерживаемый код.
  • На собеседовании приведите пример нарушения и исправления, чтобы показать понимание.
  • Избегайте крайностей: не создавайте лишних абстракций ради принципов.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы