SOLID в PHP-проекте
Вопрос
Расскажите про SOLID на примерах из PHP-кода.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
S: контроллер тонкий, логика в сервисах, доступ к данным в репозиториях
O: новые способы оплаты через новые классы, реализующие интерфейс
L: наследник не ужесточает предусловия и не бросает неожиданных исключений
I: узкие интерфейсы вместо одного большого
D: зависимость от интерфейсов, внедрение через конструктор и DI-контейнер
Без фанатизма: интерфейс там, где реально есть вариативность или граница
Что могут спросить следом
- Как DI-контейнер Laravel или Symfony помогает с DIP?
- Нарушает ли Active Record принцип единственной ответственности?
Разбор
Единственная ответственность: контроллер принимает запрос и возвращает ответ, бизнес-логика в сервисе, работа с базой в репозитории или модели, отправка писем в отдельном классе. Так каждый класс меняется по одной причине.
Открытость для расширения: когда нужно добавить платёжную систему, я добавляю класс, реализующий PaymentGateway, и регистрирую его в контейнере, а не дописываю ветку в switch.
Подстановка Лисков: наследник не должен ломать ожидания. Если ReadOnlyRepository::save() бросает исключение, значит иерархия неверна. Разделение интерфейсов: лучше Readable и Writable, чем один интерфейс на двадцать методов. Инверсия зависимостей: классы получают интерфейсы через конструктор, а реализацию подставляет контейнер Laravel или Symfony.
При этом не создаю интерфейс для каждого класса. Он нужен там, где есть несколько реализаций или граница с внешней системой, которую надо подменять в тестах.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «ООП, трейты и интерфейсы»
- Абстрактный класс или интерфейс в PHP
- Поверхностное клонирование
- Продвижение свойств в конструкторе
- Класс с интерфейсом и наследованием
- final и видимость констант
- Диспетчер событий с приоритетами
- Склад с исключениями предметной области
- Фигуры через интерфейс и абстрактный класс