1

Тема: entity manager в сущностях (идеология)

Как я понял из stackoverflow в сущностях (entity) настоятельно не рекомендуется использовать менеджер, типа надо держать код чистым и т.д.

Так получилось, что в основной работе мы используем фреймворк yii и его ОРМ Active Records. За несколько лет работы пока не приходилось сталкиваться с неудобством использования "грязных" сущностей, когда внутри нее могут быть запросы, вероятно это из-за отсутствия тестирования, но не суть.

1. Может кто-нибудь привести хороший пример чем плохи "грязные" сущности, если в проекте не пишутся тесты?
2. Каким образом в Doctrine реализовывать такие простые вещи, вроде $user->getTopComments() ? Репозитории ведь явно не подходят, т.к. они не работают с понятием текущего объекта (только если не передавать его через аргумент).

2

Re: entity manager в сущностях (идеология)

zaartix пишет:

За несколько лет работы пока не приходилось сталкиваться с неудобством использования "грязных" сущностей

Ключевое слово здесь Active Records. В нем сущность не может быть более грязной, чем она уже есть. default/smile AR просто так работает, в нем сущность — это полноценный бизнес-объект, он умеет сам себя сохранять, менять и вообще может делать что угодно, вплоть до минета. У этого подхода есть несколько больших минусов. Первый — сущность получается очень «жирная» во всех смыслах — у нее растут зависимости от других компонентов системы, она становится тяжелой и прожерливой, ее создание становится очень дорогой операцией и в нее становится практически нереально встроить какой-нибудь слой. Типичный God Object. Второй — она намертво привязывается к хранилищу, ее нельзя представить отдельно от него. Третий — для нее сложнее обеспечивать безопасность, так как будучи переданной куда угодно в любую часть приложения она может быть там изменена и сохранена, и не существует штатных способов запретить или ограничить это. Впрочем, в последнем случае у Доктрины тоже не все хорошо.

Безотносительно тестов.
1. Если захочется хранить данные сущности например в кеше, или собирать сущность из нескольких хранилищ, или например возникнет желание поменять ОРМ — грязная сущность не даст вам это сделать простым способом. Потому что у вас появляются обратные и взаимные зависимости и ваш код становится хрупким. Сущность ничего не должна знать о том, кто и как ее сохраняет и что-либо с ней делает. Ей не должно быть дела до каких-то там sql-запросов, потому что завтра вы вдруг захотите перевести ее с Мускула на MSSQL или Оракл какой-нибудь, и проще станет переписать приложение с нуля. Ей не нужно знать о менеджере, потому что завтра вы захотите сменить хранилище, а за ним и менеджер, а у вас куча зависимостей на старый. И тут мы плавно переходим к пункту 2.

2. Я конечно понимаю, что $user->getTopComments() это очень лаконично, красиво и вообще, но. С таким подходом в конечном итоге вы все равно скатитесь к God Object. Потому что понадобится постраничная навигация, сортировка, фильтрация и прочая херня. И у вас кроме безобидного с виду getTopComments к классу User добавится еще 150 методов, которые будут выбирать 5 разными способами его комментарии, букмарки, последние посты и прочую хрень. Вы получите 100500 зависимостей и бедный несчастный класс юзера на 18 тысяч строк, который зависит от всего.
Не нужно ему все это. Этим должны заниматься репозитарии, причем разные. Причем, у вас могут быть разные интерфейсы (пользовательские) с разными требованиями, и для каждого может быть свой репозитарий. И тогда объект User у вас будет легкий как перышко и не будет ломаться после каждого изменения где-то в приложении. Бонусом — вы всегда легко сможете, например, взять и закешировать те самые TopComments для пользователя и дергать их не из базы, а из кеша.
Не стесняйтесь передавать нужное через аргументы.

3 Отредактировано zaartix (2016-02-10 00:07:31)

Re: entity manager в сущностях (идеология)

огромное спасибо за столь развернутый ответ.