banderos120
@banderos120
Играю на балалайке

Doctrine ORM Лучшие практики?

Здравствуй, уважаемое сообщество !

Это не столько конкретный вопрос, сколько призыв к коллективному разуму . Многие из вас работали с Doctrine ORM и написали множество прекрасных проектов. И в ходе работы вы сталкивались с подводными камнями, типичными задачами и решениями, которымми возможно, могли бы поделиться с остальными. Ради чистоты и лаконичности кода, а так же архитектурных решений, которые ускорят разработку, давайте поделимся опытом. Возможно вам получалось создавать решения, которые были успешны (в рамках Doctrine ORM), возможно были те, которые загоняли вас в тупик.
В интернете можно найти множество best practices примеров, которые работают в рамках одной entity, но абсолютно бесполезны в реальных проектах.

От себя приведу несколько примеров:
Хорошей практикой, как я считаю, является отделение репозиториев самой доктрины, и наших репозиториев. Для работы внутри вашей бизнес логики используйте собственные классы\сервисы репозиториев, которые обязательно имплементируйте от интерфейсов.
Правила валидации для сущностей, а так же маппинг выносите в отдельные YML файлы, а не в аннотации. Это конечно спорный момент, кому что удобно, но я предпочитаю, чтобы мои сущности не зависели от ORM,
Используйтие flush с параметром, если собираетесь совершить действие только над конкретной сущностью.
Не бойтесь конструктора, прописывайте в нем зависимости вашей сущности, это сделает код более безопасным и позволит избавиться от некоторых сеттеров.
Будьте внимательны касательно новой типизации в php7 и интерфейсов, если вы создаете интерфейс для сущности и прописываете в нем возвращаемые типы, а так как же задаете скалярные типы аргументов, то после генерации Доктриной Proxy-обьектов вы получите ошибку о несоответствии класса интерфейсу. (говорят будет поправлено в 2.6 версии)
  • Вопрос задан
  • 4654 просмотра
Пригласить эксперта
Ответы на вопрос 2
by25
@by25
Веб-разработчик
  1. Никаких сеттеров. Entity всегда дожна быть валидной (установка значений через конструкторы, именованные контсрукторы). Если нужно менять состояние - делаем осмысленные методы, типа:
    public function updatePassword($plainPassword, EncoderInterface $encoder) {
        //...
    }
    public function updateProfile(UserProfile $profile) {
        //...
    }

  2. Вадидация должна происходить в приложении на более высоких слоях. (Валидируем request, command и прочее).
  3. Очень удобно использовать Embedded-object (doctrine-orm.readthedocs.io/projects/doctrine-orm/... в качестве Value-objects.
  4. flush() всегда делаем в контроллере (в верхнем слое приложения) и забываем про такую конструкцию $em->flush($myEntity); Суть такая: наше приложение работает с бизнес-объектами (domain-objects), меняет их состояние, однако про сохранение (коммит изменений) слой модели не должен знать, это не его задача. Все изменения фиксируются в конце запроса.
  5. Используйте Domain-events - очень удобная штука.
  6. Иногда очень полезно отказаться от автогенерации доктриной id, можно использовать uuid.


И дострина многим не нужна, часто достаточно active-records.
Doctrine даёт большой профит только если доменна логика сложная, ну все это хорошо ложится на проектирование по модели (DDD).
Ответ написан
fearintino
@fearintino
Php - Developer
Есть очень хорошая презентация, посмотрите.
ocramius.github.io/doctrine-best-practices/#
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы