> Какие принципы проектирования кроме SOLID существуют (PHP)

Уровень: senior · Роль: backend · Язык: PHP · Категория: Технические вопросы

Компании: vanta

Стек: PHP

> Пример ответа

Короткий ответ

Помимо SOLID существуют принципы GRASP (Information Expert, Low Coupling, High Cohesion, Polymorphism, Pure Fabrication, Indirection, Protected Variations), принципы пакетов (REP, CCP, CRP для cohesion; ADP, SDP, SAP для coupling), принципы DRY, KISS, YAGNI, Law of Demeter, принцип инверсии зависимостей как часть SOLID, а также принципы CQS/CQRS, Tell-Don't-Ask, Composition over Inheritance и принципы Domain-Driven Design (Ubiquitous Language, Bounded Context, Aggregate, Entity, Value Object). Для PHP-бэкенда особенно важны принципы пакетов и GRASP при проектировании сервисного слоя и репозиториев.

Подробное объяснение

GRASP - девять принципов назначения ответственности объектам:

  • Information Expert - ответственность у того, кто владеет данными
  • Creator - кто создаёт объект
  • Low Coupling - минимизация зависимостей между классами
  • High Cohesion - класс должен делать одно дело
  • Polymorphism - обработка вариаций через интерфейсы
  • Pure Fabrication - сервисные классы, не отражающие домен
  • Indirection - посредник для снижения связности
  • Protected Variations - защита от изменений через стабильные интерфейсы
  • Controller - единая точка входа для системных операций

Принципы пакетов (Robert Martin):

  • REP (Reuse-Release Equivalence) - пакет переиспользуется и выпускается вместе
  • CCP (Common Closure) - классы, меняющиеся вместе, - в одном пакете
  • CRP (Common Reuse) - классы, используемые вместе, - в одном пакете
  • ADP (Acyclic Dependencies) - без циклов в графе зависимостей
  • SDP (Stable Dependencies) - зависимость в сторону стабильности
  • SAP (Stable Abstractions) - стабильность пропорциональна абстрактности

Прочие принципы:

  • DRY - Don't Repeat Yourself, устранение дублирования логики
  • KISS - простота как основной критерий
  • YAGNI - не добавлять функциональность до необходимости
  • Law of Demeter - объект не должен знать внутренности других объектов
  • Tell-Don't-Ask - команды вместо запросов состояния
  • Composition over Inheritance - композиция предпочтительнее наследования
  • CQS (Command-Query Separation) - методы либо меняют состояние, либо возвращают данные

На практике

Для PHP-бэкенда на практике чаще всего применяются:

  • GRASP при проектировании сервисного слоя: сервисы как Pure Fabrication, репозитории как Indirection
  • Принципы пакетов при организации модулей в приложении, особенно если используется модульная монолитная архитектура
  • Law of Demeter при работе с ORM-сущностями, чтобы не строить цепочки $user->getProfile()->getAddress()->getCity()
  • CQS при проектировании API-контроллеров и сервисов: методы createOrder() не возвращают данные, а getOrder() не меняют состояние
  • Tell-Don't-Ask при работе с коллекциями и агрегатами: $cart->addItem($item) вместо if ($cart->getItems()->contains($item)) { $cart->getItems()->add($item); }

Пример кода

PHP
// Law of Demeter - нарушение
$cityName = $order->getCustomer()->getAddress()->getCity()->getName();
// Law of Demeter - соблюдение
$cityName = $order->getCustomerCityName();
// Tell-Don't-Ask - нарушение
if ($cart->getItems()->has($productId)) {
$cart->getItems()->updateQuantity($productId, $quantity);
} else {
$cart->getItems()->add($product);
}
// Tell-Don't-Ask - соблюдение
$cart->addOrUpdateItem($product, $quantity);
// CQS - разделение команд и запросов
final class OrderService
{
public function placeOrder(Order $order): void // команда, ничего не возвращает
{
// ...
}
public function getOrder(int $orderId): Order // запрос, не меняет состояние
{
// ...
}
}

Как отвечать на собеседовании

Начните с перечисления основных групп принципов: GRASP, принципы пакетов, поведенческие принципы (DRY, KISS, YAGNI), принципы взаимодействия объектов (Law of Demeter, Tell-Don't-Ask). Затем выберите 2-3 принципа, которые вы реально применяли в PHP-проектах, и приведите конкретный пример: как Pure Fabrication помог вынести логику из контроллера, как принципы пакетов повлияли на структуру модулей. Упомяните trade-off: например, Law of Demeter может привести к раздуванию интерфейса, а CQS усложняет кэширование. Покажите, что вы понимаете не только определения, но и контекст применения.

Что проверяет интервьюер

  • Широту технического кругозора: знаете ли вы что-то за пределами SOLID
  • Понимание назначения принципов, а не заученных формулировок
  • Умение связывать принципы с конкретными ситуациями в PHP-разработке
  • Осознание trade-off: принципы не абсолютны, иногда их нарушение оправдано
  • Способность объяснить, как принципы влияют на архитектуру реального приложения

Типичные ошибки

  • Перечисление принципов без примеров - выглядит как заучивание
  • Путаница между GRASP и SOLID, например, называть Information Expert частью SOLID
  • Игнорирование контекста PHP: принципы пакетов важны для модульных монолитов, но не для простых CRUD-приложений
  • Утверждение, что принципы нужно соблюдать всегда - интервьюер ждёт понимания trade-off
  • Смешивание CQS и CQRS: CQRS - это паттерн на уровне архитектуры, CQS - принцип на уровне методов

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью