- Никаких сеттеров. Entity всегда дожна быть валидной (установка значений через конструкторы, именованные контсрукторы). Если нужно менять состояние - делаем осмысленные методы, типа:
public function updatePassword($plainPassword, EncoderInterface $encoder) {
//...
}
public function updateProfile(UserProfile $profile) {
//...
}
- Вадидация должна происходить в приложении на более высоких слоях. (Валидируем request, command и прочее).
- Очень удобно использовать Embedded-object (doctrine-orm.readthedocs.io/projects/doctrine-orm/... в качестве Value-objects.
- flush() всегда делаем в контроллере (в верхнем слое приложения) и забываем про такую конструкцию $em->flush($myEntity); Суть такая: наше приложение работает с бизнес-объектами (domain-objects), меняет их состояние, однако про сохранение (коммит изменений) слой модели не должен знать, это не его задача. Все изменения фиксируются в конце запроса.
- Используйте Domain-events - очень удобная штука.
- Иногда очень полезно отказаться от автогенерации доктриной id, можно использовать uuid.
И дострина многим не нужна, часто достаточно active-records.
Doctrine даёт большой профит только если доменна логика сложная, ну все это хорошо ложится на проектирование по модели (DDD).