lvl1
❓ Ответы на собеседовательские вопросы
🟠 Где должна жить валидация?
Зависит от типа валидации:
- ✅ Валидация входных данных — в контроллере или
FormRequest/DTO - ✅ Валидация бизнес-правил — в сервисе
- ❌ Не в репозитории и не в модели
🟠 Что такое жирный контроллер и почему это плохо?
Жирный контроллер — это контроллер, который:
- сам вызывает модели напрямую
- содержит бизнес-логику, условия, сохранения
- много знает, много делает
Почему плохо:
- нарушает SRP
- сложно тестировать
- нет повторного использования
🟠 Чем отличается сервис от репозитория?
🔧 Сервис
Сервис — это действие, процесс, операция
Например: "создать заказ", "начислить бонус", "отправить email"
📌 Он управляет бизнес-логикой, применяет правила и координирует другие компоненты.
php КопироватьРедактировать class InvoiceService { public function create(CreateInvoiceDto $dto): void { $invoice = new Invoice(...); $this->repository->save($invoice); $this->logger->info('Created invoice'); } }
🗃 Репозиторий
Репозиторий — это доступ к данным
Например: "найти заказ по ID", "сохранить платёж", "удалить счёт"
📌 Он ничего не решает — просто сохраняет и достаёт Entity
php КопироватьРедактировать class InvoiceRepository { public function save(Invoice $invoice): void { ... } public function findById(int $id): ?Invoice { ... } }
🔑 Простое правило:
Сервис рассказывает, что делать,
Репозиторий — знает, где это взять или положить.
🟠 Как распределить ответственность?
- Контроллер: интерфейс (приём + ответ)
- Сервис: что делать (use-case)
- Репозиторий: откуда брать/куда класть
- Entity/VO: данные + локальное поведение
- Инфра: внешние вызовы (email, лог, API)
🟠 Где место бизнес-логике?
✅ В сервисах (и отчасти в сущностях, если она локальна).
❌ Не в контроллерах, ❌ не в репозиториях, ❌ не в DTO.
🟠 Что нельзя класть в модель?
- HTTP-запрос
- логеры, API-клиенты
- бизнес-решения (условия, скидки и т.д.)
- внешнюю инфраструктуру
📌 Модель (Entity) — это данные, а не действия.
✅ Архитектурный чеклист для собеса
🧠 Это мини-шпаргалка: чтобы быстро вспомнить и объяснить свою архитектуру
🔹 Слои
- Контроллер ничего не решает — делегирует в сервис
- DTO передаёт данные — без логики
- Сервис знает бизнес-правила — главный центр решений
- Репозиторий работает с БД — без логики
- Entity — сущность с данными, иногда поведением
- Инфраструктура — логеры, API, очередь и т.д.
🔹 Принципы
- Один класс — одна ответственность
- Зависимости внедряются через
__construct - Никаких
newвнутри логики (кроме фабрик) - Нет доступа к
Request,DB,Logвне границ - Всё, что можно — тестируемо отдельно
🔹 На собеседовании
Можешь сказать:
"Я разделяю приложение по слоям: контроллер, сервис, DTO, репозиторий, сущности. Это позволяет держать бизнес-логику чистой, контроллеры — тонкими, а инфраструктуру — легко заменяемой. Репозитории инкапсулируют доступ к данным, а вся логика и проверка условий — внутри сервисов. DTO нужны для типобезопасной передачи данных между слоями."