Класс начинается с ответственности
Workout отвечает за предметные переходы, VolumeCalculator вычисляет метрику, WorkoutRepository сохраняет и загружает, Clock сообщает время. Один класс не должен одновременно знать SQL, HTML и правила публикации.
Количество классов не является целью. Разделение оправдано, если компоненты меняются по разным причинам, требуют разных тестов или представляют независимые понятия языка продукта.
Композиция зависимостей
Интерфейс принадлежит потребителю
PublishWorkoutHandler требует load, save и nextVersion — ему не нужен универсальный repository с двадцатью методами. Маленький интерфейс показывает реальные зависимости и облегчает тестовую замену.
Не создавайте интерфейс для каждого класса механически. Он полезен на границе вариативности: хранилище, часы, очередь, logger. Внутренний value object может оставаться конкретным final-классом.
Наследование требует подстановки
Подкласс должен работать везде, где ожидается базовый тип, не усиливая предусловия и не ломая смысл методов. Если StrengthWorkout запрещает операцию, разрешённую Workout, и бросает неожиданное исключение, иерархия выбрана неверно.
Чаще тип тренировки является enum или отдельной стратегией расчёта, переданной через композицию. Наследование удобно для стабильного общего протокола, а не для экономии нескольких строк.
Trait — локальное включение кода
Trait может объединить небольшой технический фрагмент без собственной идентичности, например нормализацию correlation id. Он не создаёт независимый контракт и способен скрыть зависимости через методы принимающего класса.
Если trait содержит состояние, запросы к базе и множество абстрактных требований, вынесите сервис. Конфликты имён решаются синтаксисом, но конфликт ответственностей остаётся архитектурной проблемой.
Лабораторная работа
Разделите публикацию тренировки на Handler, Repository, AccessPolicy и Clock. Напишите интерфейсы только со стороны Handler и сравните тест с вариантом, где всё наследуется от BaseController.
Закрепите материал
Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.
Перелинковка со справочником
Проверка актуальности
- php-fig.orghttps://www.php-fig.org/psr/psr-3/Первичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
- php-fig.orghttps://www.php-fig.org/psr/psr-20/Первичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
Текст и схемы созданы для этого самоучителя без воспроизведения страниц, иллюстраций и листингов приложенной книги. Проверено: .