Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 12:33
Оценка: 100 (10) +3
Что-то слишком уж разнятся понимания что же такое Толстая архитектура, а что такое стройная архитектура. Слишком много терминов и разночтений. Попробую пояснить оба этих понятия.

Rich Domain Model, в простонародье, толстая модель, концепция построения логической архитектуры, в которых бизнес-объекты содержат бизнес-логику. Или можно наоборот, бизнес-логика содержит состояние бизнес-объектов.

Anemic Domain Model – почему-то некоторые называют стройной моделью, но особо и не слышал о нормальном(адекватном) русском переводе данного термина. Лично я обычно называю нетолстой моделью. Так понятней. Итак, Anemic Domain Model – концепция построение логической архитектуры, в которой состояние бизнес-объектов разнесено с объектами бизнес-логики обрабатывающих их.

Эти два термина в английском варианте я и буду использовать в дальнейшем, во избежание разночтений.

ФАУЛЕР. Фаулер дал другую терминологию: Transaction Sript и Domain Model. Под Domain Model некоторые понимают Rich Domain Model, что не является правдой, под Transaction Script – Anemic Domain Model. Но если с первым термином не очень логично, второй термин сразу ушел в небытие, и обществом принят не был.

МИФ. Существует миф, что для объектов Rich Domain Model обязательно наличие прозрачных reference между собой. Этот преступный миф не является правдой. Он не имеет отношения ни к Rich, ни к здравому смыслу. А имеет отношение к понятиям statefull, stateless и чисто опциональному lazy load. Единственное отличие, в Anemic – состояние разнесено с методами получения ссылочных объектов. В Rich – это единый объект.
В Anemic:
Employer[] OrganizationService.GetEmployers(Organization org){…}

В Rich:
Employer[] Organization.GetEmployers(){…}

Это немного, однако оно приводит к значительном различии в архитектуре. И та, и другая модель имеет те, или иные достоинства, и недостатки:

Преимущества Anemic:
1. Простота построения. Это большой плюс, ибо главная задача архитектора, реализация функциональности за меньшие деньги. 90 процентов решений, могут быть построены в данной модели и это будет на порядок дешевле.
2. Бизнес-объекты – отчуждаемы. В результате, бизнес-объект может быть спокойно пронесен от DAL, к фасаду и даже далее. Беспрепятсвенно и идентично сериализован/десериализован между физическими слоями. В большинстве, бизнес-объект как бизнес-сущность не меняется при переносе между слоями.
3. Прогнозируемость и управляемость вплоть до DAL. Что под этим понимается. В случае, если вы ворочаете большими объемами данных, в Anemic вам проще управлять запросами к базе данных, чем в Rich. База данных была и остается самой тяжелой частью бизнес приложений. Оптимизация в основном достигается за счет повышения эффективности работы с базой данных(и зачастую не обычным редактирование SQL). В Anemic, вы спокойно можете провести тот, или иной сценарий через соседний сервис, который будет работать именно над этом тяжелым сценарием. В Rich — проблема как с прогнозом результирующего запроса, и с его оптимизацией.
4. Бизнес-объект проще управлять объектами, которые еще не полностью в валидированном состоянии. В Rich – наличие валидаторов обязывает держать валидированное состояние. Что иногда выливается в проблемы(например, когда объект только что создан, не имеет идентификатора, и не имеет тех, или иных ссылок). Во многом, бизнес-объект больше похож на данные, чем на объект в стиле объектного программирования.

Преимущества Rich:
1. Простота использования. Объекты всегда под рукой. Средства обработки объектов, также под рукой. Использовать Rich – значительно проще, особенно когда в проекте новичок.
2. Инкапсуляция. Программисту, использующему данный объект, недоступно его состояние, кроме как определенный интерфейс. Это локализует некоторые изменения в логике. Но тут следует упомянуть, что те изменения, которые касаются состояния, также отслеживаются компиляцией со статической типизацией в Anemic, что покрывает большее количество таких проблем.
3. Меньшее количество мусора. В Anemic приходится отслеживать, чтобы в ворохе сервисов не делали свои велосипеды. В Rich c этим меньше проблем в силу более сильной локализации логики.

Действительность.
Чисто Anemic, а тем более Rich в абсолютно чистом виде не бывает. Бизнес-объект как минимум содержит типизацию, что является частью бизнес-логики, в Rich – по любому приходится делать более высокоуровневые сервисы.

Показания к использованию.
Во многом, IMHO, но…. Если вы ворочаете большими данными, то Anemic по любому. Если ваше приложение простое, то anemic. Если у вас большое количество сущностей, большее чем вы можете запомнить, и это не разбить на модули/компоненты/SOA, в которых будут бегать сотня программистов, то Rich. Но для Rich, нужно сразу запастись инструментальными средствами, типа Hibernate(у которого есть чудный кэш), и средства сериализации/десериализации. Это сгладит недостатки модели.

О себе.
Долгое стародавнее время писал в стиле Rich(вынужден сказать, что не по поводу). Последнее время(а это n лет) пишу только в Anemic.
Теперича можно обсуждать, осуждать, предлагать пойти в лесок с топором погуляти и etc
anemic rich domain
Re: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 27.05.09 12:47
Оценка: -1
Здравствуйте, GlebZ, Вы писали:

GZ>ФАУЛЕР. Фаулер дал другую терминологию: Transaction Sript и Domain Model.

Автор терминов Rich Domain Model и Anemic Domain Model — Фаулер.
Кратко говоря — Фаулер разбирая Domain Model говорит, что Rich — это правильная Domain Model, а Anemic — не правильная. Таким образом, к Transaction Sript это не имеет никакого отношения, если говорить о Фаулеровских терминах.
Так что прежде чем писать про Anemic vs Rich, не плохобы написать, что такое вообще Domain Model, чего я добивался еще в прошлый раз.

GZ>Под Domain Model некоторые понимают Rich Domain Model, что не является правдой,

Это ты Фаулеру скажи..

GZ>МИФ. Существует миф, что для объектов Rich Domain Model обязательно наличие прозрачных reference между собой. Этот преступный миф не является правдой. Он не имеет отношения ни к Rich, ни к здравому смыслу. А имеет отношение к понятиям statefull, stateless и чисто опциональному lazy load. Единственное отличие, в Anemic – состояние разнесено с методами получения ссылочных объектов. В Rich – это единый объект.

Либо ты сам себе противоречишь, либо я не понимаю о чем ты.

GZ>2. Инкапсуляция.

Хочешь сказать, чот в Anemic ее нет или что в Rich она выше?

GZ>Программисту, использующему данный объект, недоступно его состояние, кроме как определенный интерфейс.

Проблема только в том, что в реальной жизни один фиг в бизнес объекте есть прямой доступ к данным, максимум обернутыми в свойства. В противном случае объект должен знать обо всех сценариях своего использования и меняться при появлении каждого нового сценария.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[2]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 13:12
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, GlebZ, Вы писали:


GZ>>ФАУЛЕР. Фаулер дал другую терминологию: Transaction Sript и Domain Model.

IB>Автор терминов Rich Domain Model и Anemic Domain Model — Фаулер.
+1
IB>Кратко говоря — Фаулер разбирая Domain Model говорит, что Rich — это правильная Domain Model, а Anemic — не правильная. Таким образом, к Transaction Sript это не имеет никакого отношения, если говорить о Фаулеровских терминах.
-1 Только не тебе, а Фаулеру. В книжке, в которой он полновесно хотел описать все паттерны, он вполне справедливо запутался. Если брать саму постановку вопроса — то Anemic и Transaction Script, одно и то же. Далее, после данной книги, когда оказалось что Transaction Script может описывать предметную область, а он это не учел, то тут и начался у него переполох в уме.
IB>Так что прежде чем писать про Anemic vs Rich, не плохобы написать, что такое вообще Domain Model, чего я добивался еще в прошлый раз.
Что такое модель предметной области? Она есть всегда и везде. Ибо по ней и создается архитектура.

GZ>>Под Domain Model некоторые понимают Rich Domain Model, что не является правдой,

IB>Это ты Фаулеру скажи..
Ежели смотреть обсуждения нескольких лет назад, то ему это уже говорили. Что и породило новую терминологию.

GZ>>МИФ. Существует миф, что для объектов Rich Domain Model обязательно наличие прозрачных reference между собой. Этот преступный миф не является правдой. Он не имеет отношения ни к Rich, ни к здравому смыслу. А имеет отношение к понятиям statefull, stateless и чисто опциональному lazy load. Единственное отличие, в Anemic – состояние разнесено с методами получения ссылочных объектов. В Rich – это единый объект.

IB>Либо ты сам себе противоречишь, либо я не понимаю о чем ты.
Ничего не противоречу. Между функцией получения, и ссылкой есть большая разница. И она сколько не физическая, а логическая.

GZ>>2. Инкапсуляция.

IB>Хочешь сказать, чот в Anemic ее нет или что в Rich она выше?
Я это уже сказал.

GZ>>Программисту, использующему данный объект, недоступно его состояние, кроме как определенный интерфейс.

IB>Проблема только в том, что в реальной жизни один фиг в бизнес объекте есть прямой доступ к данным, максимум обернутыми в свойства. В противном случае объект должен знать обо всех сценариях своего использования и меняться при появлении каждого нового сценария.
Ну возьмем к примеру ACL. ACL как данные, программисту не нужны, а иногда вредны. А вот средства проверки ACL для той или иной операции востребованы, и вполне могут жить в объекте.
Re[3]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 27.05.09 13:23
Оценка: -1
Здравствуйте, GlebZ, Вы писали:

GZ>Что такое модель предметной области? Она есть всегда и везде. Ибо по ней и создается архитектура.

Эта "модель предметной области" всегда напрямую выражается в коде?

GZ>Ничего не противоречу. Между функцией получения, и ссылкой есть большая разница. И она сколько не физическая, а логическая.

Хрен редьки не слаще.

IB>>Хочешь сказать, чот в Anemic ее нет или что в Rich она выше?

GZ>Я это уже сказал.
Ну и зря, инкапсуляция в стройной модели ничуть не ниже, а как правило и выше.

GZ>Ну возьмем к примеру ACL. ACL как данные, программисту не нужны, а иногда вредны. А вот средства проверки ACL для той или иной операции востребованы, и вполне могут жить в объекте.

так прикладному программисту они действительно не нужны, а тому, который всю логику вокург ACL реализует, очень даже пригодятся.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.05.09 13:43
Оценка: -1
Здравствуйте, GlebZ, Вы писали:


GZ>Преимущества Rich:

GZ>2. Инкапсуляция. Программисту, использующему данный объект, недоступно его состояние, кроме как определенный интерфейс. Это локализует некоторые изменения в логике.
Недоступно состояние? а как пользователю на экране это недступное состояние показать?
А если есть функционал, затрагивающий несколько объектов?

Кстати, инкаписуляция != data hiding.
Re[4]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 13:47
Оценка: +1
Здравствуйте, IB, Вы писали:

IB>Эта "модель предметной области" всегда напрямую выражается в коде?

Зависит от архитектора. Модель предметной области — термин постановки а не архитектуры. В лучшем случае, набор документации написанной постановщиком, в худшем — абстрактная модель в голове программиста.

IB>Хрен редьки не слаще.

Вопрос инстанцирования? Я вполне нормально описал в чем разница, и что не надо путать.

IB>>>Хочешь сказать, чот в Anemic ее нет или что в Rich она выше?

GZ>>Я это уже сказал.
IB>Ну и зря, инкапсуляция в стройной модели ничуть не ниже, а как правило и выше.
Если ты об этом? здесь
Автор: IB
Дата: 25.10.07
То это был неправильный твой перевод. Говорилось о вреде излишней инкапсуляции(в чем я абсолютно согласен ибо уменьшают cohesion), а не о том что она выше. По крайней мере — это смешно... Открытые данные более инкапсулированы чем приватные.

GZ>>Ну возьмем к примеру ACL. ACL как данные, программисту не нужны, а иногда вредны. А вот средства проверки ACL для той или иной операции востребованы, и вполне могут жить в объекте.

IB>так прикладному программисту они действительно не нужны, а тому, который всю логику вокург ACL реализует, очень даже пригодятся.
Об этом и разговор. У прикладника нет возможности влезть в логику куда ему лезть не стоит.
Re[2]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 13:56
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

GZ>>2. Инкапсуляция. Программисту, использующему данный объект, недоступно его состояние, кроме как определенный интерфейс. Это локализует некоторые изменения в логике.

G>Недоступно состояние? а как пользователю на экране это недступное состояние показать?
G>Кстати, инкаписуляция != data hiding.
Блин.... Ёкарный бабай. Ну ты тыкни где я писал что инкапсуляция = data hiding. Найди выдели и тыкни пальцем и выругайся. Мы понимать что написано умеем? Мне нужно описывать все терминалогию, от инкапсуляции до понятия байта?

G>А если есть функционал, затрагивающий несколько объектов?

А ты всегда и все показываешь? Списки доступа, гуиды, средства построения деревьев при адресации по идентификаторам?
Re[3]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 13:57
Оценка:
Здравствуйте, GlebZ, Вы писали:

Неправильно откопировал
G>>Недоступно состояние? а как пользователю на экране это недступное состояние показать?
GZ>А ты всегда и все показываешь? Списки доступа, гуиды, средства построения деревьев при адресации по идентификаторам?
Re[3]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.05.09 14:05
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, gandjustas, Вы писали:


GZ>>>2. Инкапсуляция. Программисту, использующему данный объект, недоступно его состояние, кроме как определенный интерфейс. Это локализует некоторые изменения в логике.

G>>Недоступно состояние? а как пользователю на экране это недступное состояние показать?
G>>Кстати, инкаписуляция != data hiding.
GZ>Блин.... Ёкарный бабай. Ну ты тыкни где я писал что инкапсуляция = data hiding. Найди выдели и тыкни пальцем и выругайся.
Выделил. Если надо показывать на экране, то это data hiding.

G>>А если есть функционал, затрагивающий несколько объектов?

GZ>А ты всегда и все показываешь? Списки доступа, гуиды,
нет, я их даже не считываю.

GZ>средства построения деревьев при адресации по идентификаторам?

такое тоже в базе хранится?
Re: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 27.05.09 14:09
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Что-то слишком уж разнятся понимания что же такое Толстая архитектура, а что такое стройная архитектура. Слишком много терминов и разночтений. Попробую пояснить оба этих понятия.


[..]

GZ>Показания к использованию.

GZ>Во многом, IMHO, но…. Если вы ворочаете большими данными, то Anemic по любому. Если ваше приложение простое, то anemic. Если у вас большое количество сущностей, большее чем вы можете запомнить, и это не разбить на модули/компоненты/SOA, в которых будут бегать сотня программистов, то Rich. Но для Rich, нужно сразу запастись инструментальными средствами, типа Hibernate(у которого есть чудный кэш), и средства сериализации/десериализации.
Это сгладит недостатки модели.

Можно вставить свои пять копеек по поводу использования? Вы говорите о том, что нужно выбрать; наверное, правильнее будет говорить о том, в какую сторону делать уклон, потому что в чистом виде все равно не получится.
Ну и вдобавок что хотел сказать по поводу критериев выбора -- есть еще понятие data-centric и object-centric model. Если вы придерживаетесь первого (data-centric), то стоит двигаться в сторону anemic. Если object-centric -- то к RichModel. Потому как на примере своего приложения -- несмотря на то, что очень много сущностей, но за счет их data-centric природы anemic model неплохо удовлетворяет нужды.

И еще -- если есть колебания, что выбрать, можно грубо можно пользоваться простой аналогией: Rich Model <--> Active Record. Если AR устраивает, можно выбирать rich model, если же выглядит неприемлемой -- стоит грести к anemic.
Re[4]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 14:15
Оценка: +1 -1
Здравствуйте, gandjustas, Вы писали:

GZ>Программисту, использующему данный объект, недоступно его состояние, кроме как через определенный интерфейс.

Объясняю. Только не выделенное, а всю фразу. Чтобы параноидально по полочкам.
Инкапсуляция — средство локализации функционала в сухом и потребном месте. Для локализации функционала, нужно иметь некоторый интерфейс(в фразе это слово присутсвует). Все что за этим интерфейсом, как бы то ни было, данные, функции, объекты, мамонты и мамонтихи, скрываются. Таким образом, я нигде не писал что data hiding=incapsulation. Но то что data hiding может являться средством инкапсуляции, и в большинстве случаев для людей с головой является таковым, я как то даже стесняюсь говорить.
Re[5]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 27.05.09 14:53
Оценка: -1
Здравствуйте, GlebZ, Вы писали:

GZ>Зависит от архитектора.

GZ>Модель предметной области — термин постановки а не архитектуры. В лучшем случае, набор документации написанной постановщиком, в худшем — абстрактная модель в голове программиста.
Отлично, так в какой момент это все переходит в Domain Model в терминах Фаулера? он-то говорит именно об архитектурном решении.

GZ>Вопрос инстанцирования? Я вполне нормально описал в чем разница, и что не надо путать.

Вопрос использования.

IB>То это был неправильный твой перевод.

Правильный.

IB>Говорилось о вреде излишней инкапсуляции(в чем я абсолютно согласен ибо уменьшают cohesion), а не о том что она выше.

Именно о том, что она выше.

IB> По крайней мере — это смешно... Открытые данные более инкапсулированы чем приватные.

В том-то и дело, что не будут они у тебя приватными, в реальной жизни. Иначе получается как раз та самая "излишняя инкапсуляция"

GZ>Об этом и разговор. У прикладника нет возможности влезть в логику куда ему лезть не стоит.

Не об этом, а о том, что у того, кто разрабатывает логику работы вокруг ACL все равно придется делать это отдельной сущностью, так как всю эту логику в отдельный класс не запихнешь уж очень она развесистая.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 14:57
Оценка: +2
Здравствуйте, GlebZ, Вы писали:

МИФЫ ходящие по rsdn.
МИФ №2
Вся логика находися в бизнес-объекта. Господа и товарищи... Никто из приверженцев Rich модели из ума не выжил. Сложные сценарии не инкапсулируются в самих бизнес-объектах.

Миф №3
У толстой модели нет единой точки входа. Точка входа всегда есть. Называется фасад. Для него больше придется положить усилий и трудов, но он есть. И в нем, можно создавать контексты транзакций, аутентификацию, и проводить сериализацию.
Re[6]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 27.05.09 16:15
Оценка: 4 (1) +1
Здравствуйте, IB, Вы писали:

IB>Отлично, так в какой момент это все переходит в Domain Model в терминах Фаулера? он-то говорит именно об архитектурном решении.

Ладно, поехали снова. Мне кажется мы больше издеваемся друг над другом, чем ищем вселенское благо. Давай забудем об архитектуре как таковой, а займемся буквоедством, то бишь паттернами.
Берем сайт Фаулера:
Для Domain Model:

An object model of the domain that incorporates both behavior and data.

Для Transaction Script:

Organizes business logic by procedures where each procedure handles a single request from the presentation.

Надо отдать ему должное, в его вышеупомянутой книжке описывается то же самое.
Первое что бросается в глаза для Domain Model — both behavior and data. Чудненько и прекрасно. Очень похоже на Rich, если бы не абстрактный object model под которым можно понимать все что угодно.
Второе — Transaction Script. И совершенно ничего не говорится о том, что сами параметры процедур, точно также могут описывать предметную область. И тут начинается буза. С одной стороны, если мы используем бизнес объекты в Transaction Script, то чем это не object model? Можно спокойно построить логическую диаграмму объектов. То есть это же получится Domain Model? Фаулер вышел из этой загвоздки, разделением понятия Domain Model на паттерн и антипаттерн. Ну что же делать, дикари-с. Впрочем он никогда и не скрывал, что Anemic — это смесь Domain Model и Transaciton Script.

GZ>>Вопрос инстанцирования? Я вполне нормально описал в чем разница, и что не надо путать.

IB>Вопрос использования.
Перечитай весь параграф. Я говорил именно об инстанцировании.

IB>> По крайней мере — это смешно... Открытые данные более инкапсулированы чем приватные.

IB>В том-то и дело, что не будут они у тебя приватными, в реальной жизни.
Смотря для кого? DAL — это также инкапсуляция работы с БД. Мы не говорим что оно инкапсулировано от самих объектов DAL. Но оно инкапсулировано относитель BLL, и изолировано от слоя еще выше.
IB>Иначе получается как раз та самая "излишняя инкапсуляция"
Инкапсуляция не может быть измерена. В отличие от Low Cohesion, High Coupling.

GZ>>Об этом и разговор. У прикладника нет возможности влезть в логику куда ему лезть не стоит.

IB>Не об этом, а о том, что у того, кто разрабатывает логику работы вокруг ACL все равно придется делать это отдельной сущностью, так как всю эту логику в отдельный класс не запихнешь уж очень она развесистая.
Абсолютно верно. Но тут как раз два подхода. Для одного подхода — это сервис. Для второго подхода, это вопрос иерархии наследования.
Кстати, это действительно интересный пример разницы:
Например, в случае anemic:
bool ACLService.CanEdit(Guid id, Guid idUser);
в случае Rich:
bool MyEditableObject.CanEdit(Guid idUser);
Вызовы похожи, а вот реализация совершенно разная.
В первом случае, мы имеем сервис в котором мы можем получить подсчитать список доступа для данного объекта, например какие пользователи могут пользоваться этим объектом и закэшировать эту инфу в самом сервисе. Нам не нужен сам объект по сути. Мы вполне можем его не загружать когда он не требуется.
Во втором случае, мы можем в Lazy Load точно также рассчитать реальный ACL через определенный сервис, и хранить его в самом объекте, закэшировав сам объект. Второе в данном случае менее эффективно потому как приходится загружать объект, но несколько более эффектиный кэш. Пока не изменен список доступа определенного пользователя все более менее, но если он поменялся. В результате, в ACLService мы вполне достойно можем почистить кэш контролируемый нами. А в случае с бизнес объектом, нам придется высчитывать кто есть лишний на этом празднике жизни, и как ему об этом сообщить. Задача вполне решаемая, но все таки обладающая некоторой трудоемкостью.
Далее, тут у нас начинается коренная доработка, в которой говорится что доступ к MyEditableObject складывается от ACL не только самого объекта, но еще и его непосредственного parent. И тут начинаются траблы. Использовать ACLService.CanEdit мы никаким боком использовать не можем, поскольку для выдачи решения нам не хватает информации. Injection тут не поможет по той же причине, и нам приходится героически переделывать вызовы сервиса там, где информация о том что это именно MyEditableObject присутсвует. В случае Rich — нам достаточно переделать реализацию CanEdit, ну например, на вызов return ACLService.CanEdit(id, parentId, userId) или вообще сделать ACLEditableObjService. Инкапсуляция в действии.
Так что лезвие бритвы — инкапсуляция выше, ресурсоемкость тоже.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 27.05.09 17:37
Оценка: -1
Здравствуйте, GlebZ, Вы писали:

GZ>Organizes business logic by procedures where each procedure handles a single request from the presentation.

Какое-то странное определение, ограничивающие Transaction Script презентацией, типа логики не может быть вообще.

GZ>Первое что бросается в глаза для Domain Model — both behavior and data. Чудненько и прекрасно. Очень похоже на Rich, если бы не абстрактный object model под которым можно понимать все что угодно.

Это ты уже спекуляциями начинаешь заниматься — гаданием по Фаулеру, что же он имел ввиду.

GZ> Впрочем он никогда и не скрывал, что Anemic — это смесь Domain Model и Transaciton Script.

Единственное что он говорил по этому поводу — "Какой кошмар, это же почти Transaction Script, это не ООП, а процедурное программирование" (С)

GZ>Я говорил именно об инстанцировании.

А я об использовании.

GZ>Смотря для кого?

Для всего. У свойства дающего прямой доступ к данным стоит модификатор public.

GZ>Но оно инкапсулировано относитель BLL, и изолировано от слоя еще выше.

Каким боком?

GZ>Инкапсуляция не может быть измерена.

Инкапсуляция отлично меряется, что подробно расписано у того же Меерса.

GZ>Использовать ACLService.CanEdit мы никаким боком использовать не можем, поскольку для выдачи решения нам не хватает информации.

Мы можем прекрасным образом использовать ACLService.CanEdit передав ему всю необходимую информацию — либо самого parent-а, либо построив бизнес объект таким образом, чтобы вся необходимая информация уже была в нем.
Разница лишь в том, что в отличии от Rich ты сделаешь это явно, причем именно там где полагается — при обращении к ACL, а в случае Rich, спустя какое-то время ты будешь сильно удивляться — какого хрена при обращении к MyObj.CanEdit он еще и к родителю лезет.

GZ> В случае Rich — нам достаточно переделать реализацию CanEdit,

В стройной модели тоже самое.

GZ> Инкапсуляция в действии.

Во-во, излишняя инкапсуляция в действии.

GZ>Так что лезвие бритвы — инкапсуляция выше, ресурсоемкость тоже.

Я думаю — ты уже понял, где ошибался? =)
Мы уже победили, просто это еще не так заметно...
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 28.05.09 02:41
Оценка:
Здравствуйте, GlebZ, Вы писали:

А знаете в чём здесь загвоздка?

Надо разделять БЛ и логику предметной области (намеренно не использую слово Domain, т.к. его все по разному понимают).

Что такое предметная область? Это грубо говоря поле игры заказчика, то что никак не зависит от его желаний/способа организации бизнеса.

Например независимо от желания аэроперевозчика у самолётов конечная вместимость. Ограничение на нерастяжимость самолёта — часть предметной области и по-хорошему должно проверяться силами самой model (в идеале при попытке изменения в дополнение к проверке при сохранении изменений).

И так набирается куча логики, которая к самой БЛ никакого отношения не имеет. Разгрузка БЛ позволяет нехило упростить саппорт и изменение — т.к. БЛ выглядит как последовательность операций над предметной областью, элементарно расписывается и проверяется даже неспециалистами в программировании.

Ещё одно достоинство — перекрёстная проверка. Если вас какое-то требование не укладывается в модель, то либо заказчик гонит пургу, либо у вас кривая модель предметной области.

Об этом Эванс неплохо писал в "Domain-driven-design: tackling the complexity in the heart of software". Правда во второй части он зачем-то опровергает сам себя и смешивает БЛ и domain model обратно

Проблему надо просто решать на уровне архитектуры приложения а не ждать пока она вылезет в кривом дизайне DAL/контроллера. Тогда и не будет споров "anemic vs rich" и "mvc or not mvc".

Any comments?
Re[2]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 28.05.09 05:56
Оценка:
Здравствуйте, meowth, Вы писали:

M>И еще -- если есть колебания, что выбрать, можно грубо можно пользоваться простой аналогией: Rich Model <--> Active Record. Если AR устраивает, можно выбирать rich model, если же выглядит неприемлемой -- стоит грести к anemic.


-1, но что-то в этом есть.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[8]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 28.05.09 06:15
Оценка: 18 (1)
Здравствуйте, IB:

IB>Единственное что он говорил по этому поводу — "Какой кошмар, это же почти Transaction Script, это не ООП, а процедурное программирование" (С)


Если я нигде ничего не вру, там шла речь в контексте реализации UoW, да ещё и бизнес-процессы упоминались (мы говорим о его книжке "enterprise что-тотам"?).

А ООП как ни странно немногое здесь может предложить, т.к. задача ближе к реализации workflow модели. Я говорю не реализации отдельных кирпичиков, а именно об управлении процессами. И тут проблема о двух концах — либо у нас мегауниверсальные кирпичики, и трёхтомное "введение в конфигурацию для начинающих", либо кирпичики пишутся под задачи, но тогда уж не обижайтесь на "процедурное программирование".

Кстати, не втыкали в большинство описаний "типовых моделей бизнес процессов"? Там в основном идёт речь именно о воркфлоу как поэтапном изменении состояния. И процессы и ресурсы явно ставятся ортогонально друг другу. Так что это чуть ли не специфика бизнес-логики выходит.
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 28.05.09 06:43
Оценка: 1 (1)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, GlebZ, Вы писали:


S>А знаете в чём здесь загвоздка?


S>Надо разделять БЛ и логику предметной области (намеренно не использую слово Domain, т.к. его все по разному понимают).

S>Что такое предметная область? Это грубо говоря поле игры заказчика, то что никак не зависит от его желаний/способа организации бизнеса.
Наведите порядок в терминологии. Есть части BL — business-rules — правила валидации модели и business-transactions — операции переводящие модель из одного состояния в другое.
В подавляющем большинстве случаев business-transactions сводятся к транзакциям БД. В более сложных случаях имеет смысл умышленно сводить бизнес-транзакции к системным транзакциям.

S>Например независимо от желания аэроперевозчика у самолётов конечная вместимость. Ограничение на нерастяжимость самолёта — часть предметной области и по-хорошему должно проверяться силами самой model (в идеале при попытке изменения в дополнение к проверке при сохранении изменений).

А вот тут возникает самый нтересный вопрос: когда проверять business-rules.

Приверженцы DDD и зирной модели предлагают все засунуть в объекты и проверять чуть ли не при каждом изменении полей. Но такая реализация очень плохо работает, особенно для сложных правил, где требуется задействовать несколько объектов.
Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.

Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям. Например самолет: хоть у него и конечная вместимость, но это имеет смысл только при операции погрузки.


ЗЫ. Я еще не упоминул про busines-operations, которые состоят из множества business-transactions, возможо растянутых по времени.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 28.05.09 07:22
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Приверженцы DDD и зирной модели предлагают все засунуть в объекты и проверять чуть ли не при каждом изменении полей.


Можно ссылку на выделенное?

G> Но такая реализация очень плохо работает, особенно для сложных правил, где требуется задействовать несколько объектов.

G>Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.

Мне кажется ты приписываешь DDD выдуманные недостатки, а потом их сокрушительно критикуешь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 28.05.09 08:00
Оценка: +2
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, gandjustas, Вы писали:


G>>Приверженцы DDD и зирной модели предлагают все засунуть в объекты и проверять чуть ли не при каждом изменении полей.


Z>Можно ссылку на выделенное?

Я ссылки не собираю. Можно посмотреть что тут пишут на форуме приверженцы жирной модели. Даже большой холивар был на эту тему.

G>> Но такая реализация очень плохо работает, особенно для сложных правил, где требуется задействовать несколько объектов.

G>>Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.

Z>Мне кажется ты приписываешь DDD выдуманные недостатки, а потом их сокрушительно критикуешь.

Я их не выдумываю. Их выдумывают приверженцы DDD. Напрмер aggregation root — огромный костыль DDD, который не я придумал. Также недавно тут пробегала ссылка на статью, которая рассказывала что reporting (практически любое отображение информации) надо делать не DDDшными средствами.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 28.05.09 08:03
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Наведите порядок в терминологии. Есть части BL — business-rules — правила валидации модели и business-transactions — операции переводящие модель из одного состояния в другое.


Речь идёт слегка не о том: в поведении приложения есть грубо говоря два уровня ограничений: что оно может делать и что от приложения хочет заказчик. Возвращаясь к аналогии с авиаперевозчиком, полётные планы (а это не только ограничения, это куча муторной логики) должны быть зарегистрированы и соответствовать стандартам — это часть предметной области. Разумеется, работа с _конкретными_ планами (нюансы типа соответствия законодательству кучи стран) — это как раз бизнес логика.

Разница тут совсем неочевидна, но чем больше у вас разноплановых взаимодействующих систем, тем проще её увидеть.



G>А вот тут возникает самый нтересный вопрос: когда проверять business-rules.
Согласен. Сразу disclaimer — я говорю главным образом о толстых клиентах со statefull-логикой.

G>Приверженцы DDD и зирной модели предлагают все засунуть в объекты и проверять чуть ли не при каждом изменении полей. Но такая реализация очень плохо работает, особенно для сложных правил, где требуется задействовать несколько объектов.


Ну про DDD не надо. Эванс в первой части (когда он рассказывает что такое модель предметной области) нехило противоречит сам себе во второй (когда он начинает лепить всё в одну кучу).

Кстати, у нас локальная валидация на клиентах именно так и работает. Не всех ограничений конеш, а именно ограничений предметной области, их обычно немного. Да и то, это в основном не валидация пользовательского ввода (это к UI layer), а ассерты для поиска багов. Ещё я не совсем понял почему "проверки на каждый чих" — это признак Rich модели: эти проверки вполне могут быть оторваны от конкретного представления данных.

Скорее всего у нас просто разные предметные области — я первый убъюсь об стену если потребуется делать сложную валидацию на stateless аппсервере.

G>Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.


А эти варианты не отменяют друг друга: проверка при сохранении обязательно должна быть и в идеале должна делаться силами СУБД.



G>Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям. Например самолет: хоть у него и конечная вместимость, но это имеет смысл только при операции погрузки.

Эххх... Я тоже так думал. А потом радостно убивался об стену. Чем больше систем работает с одними и теми же данными — тем больше коллизий.
Тут речь идёт даже не о загрузке самолёта, а о информации о конкретном рейсе. Эта информация используется при бронировании билетов (тут тоже целый цирк включая работу с турагенствами), уходит в отчёт что подаётся при регистрации вылета (сорри, терминологию сильно подзабыл, да и не специалист я, так, интересовался), ещё может понадобиться в налоговую/для отчётов и аналитики.

В идеале информация о местах _изменяться_ будет в двух сценариях: бронирование билетов и покупка билетов. Но даже в этих двух сценариях структура данных будет очень нехило различаться, общих пересечений будет не так уж и много. Поэтому проще сделать сервис резервирования мест (будет дёргаться при начале обслуживания) и проверки в СУБД при любом изменении соответствующих данных.

Почему при любом? Потому что самолёт может быть заменён в любой момент (не совсем так, для простоты оставим), разорваться договор на транзит и т.п.
Причём заметьте — эти нюансы нифига не бизнес логика, про них стараются не упоминать в требованиях (ну кто ж признается что у него самолёты по пять раз на дню в сервисе). Эту инфу можно выудить либо очень тщательно покопавшись в предметной области самостоятельно, либо после кучи интерьвю со сторонними специалистами. Причём со специалистами, которые могут связно объяснить как оно работает и почему именно так. Это настоящий талант, и таких людей бывает крайне тяжко найти.

G>ЗЫ. Я еще не упоминул про busines-operations, которые состоят из множества business-transactions, возможо растянутых по времени.


Охх. Это отдельная тема. И так раздули.

P.S. Если я вас напрягаю — скажете, закруглимся
Re[9]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 08:09
Оценка: 12 (1)
Здравствуйте, Sinix, Вы писали:

S>Если я нигде ничего не вру, там шла речь в контексте реализации UoW, да ещё и бизнес-процессы упоминались (мы говорим о его книжке "enterprise что-тотам"?).

Нет. Речь шла о его статье про антипаттерн Anemic Domain Model. (http://www.martinfowler.com/bliki/AnemicDomainModel.html)
Конкретно:

By pulling all the behavior out into services, however, you essentially end up with Transaction Scripts, and thus lose the advantages that the domain model can bring.

Правда дальше у него идет оговорочка

As I discussed in P of EAA, Domain Models aren't always the best tool.

Но он нигде не говорит, что же это за такие advantages, которые domain model can bring.

S>А ООП как ни странно немногое здесь может предложить, т.к. задача ближе к реализации workflow модели. Я говорю не реализации отдельных кирпичиков, а именно об управлении процессами.

А что за проблемы у ООП с управлением процессами?

S> И тут проблема о двух концах — либо у нас мегауниверсальные кирпичики, и трёхтомное "введение в конфигурацию для начинающих", либо кирпичики пишутся под задачи, но тогда уж не обижайтесь на "процедурное программирование".

Бррр... Собственно я с Фаулером не согласен прежде всего в том, что Anemic — это процедурное программирование. Он там еще пишет, что ОО-дизайн — это обязательно логика вместе с данными, так вот это полная пурга, как-то он очень узко и наивно ОО-дизайн представляет. Как только данные становятся персистентными, делать им вместе с логикой нечего — жизненный цикл разный, но при этом это ни на каплю не противоречит правильному ОО-дизайну.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 28.05.09 08:33
Оценка: +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Наведите порядок в терминологии. Есть части BL — business-rules — правила валидации модели и business-transactions — операции переводящие модель из одного состояния в другое.


S>Речь идёт слегка не о том: в поведении приложения есть грубо говоря два уровня ограничений: что оно может делать и что от приложения хочет заказчик. Возвращаясь к аналогии с авиаперевозчиком, полётные планы (а это не только ограничения, это куча муторной логики) должны быть зарегистрированы и соответствовать стандартам — это часть предметной области. Разумеется, работа с _конкретными_ планами (нюансы типа соответствия законодательству кучи стран) — это как раз бизнес логика.

С точки зрения программы все равно откуда взялись требования — является ли это желанием заказчика или каким-либо законом.

S>Разница тут совсем неочевидна, но чем больше у вас разноплановых взаимодействующих систем, тем проще её увидеть.

Разницы на самом деле нету, она только в голове проектировщика.

S>

G>>А вот тут возникает самый нтересный вопрос: когда проверять business-rules.
S>Согласен. Сразу disclaimer — я говорю главным образом о толстых клиентах со statefull-логикой.
Такие случаи требуют отдельного рассотрения так как размазывание логики между клиентом и сервером создает дополнительные проблмемы, которые не связаны с постановкой задачи.
Я вообще склонен считать такие случаи паталогическими.

S>Кстати, у нас локальная валидация на клиентах именно так и работает. Не всех ограничений конеш, а именно ограничений предметной области, их обычно немного. Да и то, это в основном не валидация пользовательского ввода (это к UI layer), а ассерты для поиска багов.

Для поиска багов лучше тесты.

S>Ещё я не совсем понял почему "проверки на каждый чих" — это признак Rich модели: эти проверки вполне могут быть оторваны от конкретного представления данных.

Проверки на каждый чих избыточны. Реально необходима только одна проверка при сохранении данных. Для удобства пользователей делают дополнительные проверки.
Если же проверки засунты в объекты, то проверки будут именно на каждый чих.

S>Скорее всего у нас просто разные предметные области — я первый убъюсь об стену если потребуется делать сложную валидацию на stateless аппсервере.

От предметтной области мало зависит главное правильно разделить на business-rules и preconditions чтобы ничего лишнего не проверять.

G>>Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.

S>А эти варианты не отменяют друг друга: проверка при сохранении обязательно должна быть и в идеале должна делаться силами СУБД.
Как уже писал выше при наличии проверки при сохранении остальные проверки только для удобства.

S>

G>>Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям. Например самолет: хоть у него и конечная вместимость, но это имеет смысл только при операции погрузки.

S>Эххх... Я тоже так думал. А потом радостно убивался об стену. Чем больше систем работает с одними и теми же данными — тем больше коллизий. (*остальное опущено*)


Все что написано сильно зависит от предметной области и желаний заказчика.
Re[10]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 28.05.09 08:48
Оценка: +2 :))
Здравствуйте, IB!

IB>Нет. Речь шла о его статье про антипаттерн Anemic Domain Model. (http://www.martinfowler.com/bliki/AnemicDomainModel.html)

Ну вот — влез не с тем и не туда

S>>А ООП как ни странно немногое здесь может предложить, т.к. задача ближе к реализации workflow модели. Я говорю не реализации отдельных кирпичиков, а именно об управлении процессами.

IB>А что за проблемы у ООП с управлением процессами?
Эххх, мой кривой язык...
Проблемы не у ООП, а у товарищей что пытаются изобразить динамически конфигурируемый DSL силами ООП.


S>> И тут проблема о двух концах — либо у нас мегауниверсальные кирпичики, и трёхтомное "введение в конфигурацию для начинающих", либо кирпичики пишутся под задачи, но тогда уж не обижайтесь на "процедурное программирование".

IB>Бррр... Собственно я с Фаулером не согласен прежде всего в том, что Anemic — это процедурное программирование.
Да-да, тут вы меня поняли верно.

IB> Он там еще пишет, что ОО-дизайн — это обязательно логика вместе с данными, так вот это полная пурга, как-то он очень узко и наивно ОО-дизайн представляет. Как только данные становятся персистентными, делать им вместе с логикой нечего — жизненный цикл разный, но при этом это ни на каплю не противоречит правильному ОО-дизайну.

+5.

Закругляемся? // А то щас долго расшаркиваться будем какие мы оба хорошие...
Re[11]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 28.05.09 09:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>С точки зрения программы все равно откуда взялись требования — является ли это желанием заказчика или каким-либо законом.

G>Разницы на самом деле нету, она только в голове проектировщика.

Щасс ответим — это вы хорошую тему подняли

Не обижайтесь, но у вас какое-то идеализированное представление о проектировании систем — берём требования, реализуем и все щасливы. Нифига!


Грубо говоря требования описывают внешний интерфейс системы (не только и не столько UI разумеется), а ограничения предметной области позволяет обоснованно говорить о дизайне системы. Во всяком случае, с большей уверенностью чем при проектировании от требований

Разумеется, в жизни не всё так радужно, но если видите что я где-то не прав — давайте разберём по пунктам, ок?




G>Такие случаи требуют отдельного рассотрения так как размазывание логики между клиентом и сервером создает дополнительные проблмемы, которые не связаны с постановкой задачи.

G>Я вообще склонен считать такие случаи паталогическими.
G>Для поиска багов лучше тесты.

Видно я невнятно написал — здесь я с вами в принципе согласен. Сама логика может жить и на сервере — ничего не мешает. Дело именно в общих проверках, независимых от конкретного сценария.

[ОФФТОП]
Про тесты: одно другого не отменяет. Лично мне куда проще саппортить такой код:
void SomeMethod(string arg1, params int[] indexes)
{
  Code.NotNullOrEmpty(arg1, "arg1");
  Code.NotNull(indexes, "indexes");
  Code.GreaterThenOrEqual(indexes.Length, "indexes.Length", 5);
  Code.AssertState(CanDoSomeOperation, @"Some detailed exception message");

  // code goes here
}


Сразу виден data contract + есть возможность отключать проверки по необходимости.
[/ОФФТОП]

G>Проверки на каждый чих избыточны. Реально необходима только одна проверка при сохранении данных. Для удобства пользователей делают дополнительные проверки.

G>Если же проверки засунты в объекты, то проверки будут именно на каждый чих.

Ну да, я примерно это и имел в виду: проверки при изменении в основном работают в UI layer и в основном для удобства пользователей. Ассерты — это так, дополнительная подстраховка, к тому же отключаемая.
Re[11]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 28.05.09 09:29
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Я ссылки не собираю. Можно посмотреть что тут пишут на форуме приверженцы жирной модели. Даже большой холивар был на эту тему.


Глядя на количество негативных постов про .net еще не пропало желание его использовать? Я вот регулярно натыкаюсь на ругательства по поводу быстродействия, GC, JIT и C# от людей которые только что вошли в технологию.

G>Я их не выдумываю. Их выдумывают приверженцы DDD. Напрмер aggregation root — огромный костыль DDD, который не я придумал.


Чем он ужасен? Что мешает отказаться от него в случаях когда он приносит неудобства? Каким образом

G> Также недавно тут пробегала ссылка на статью, которая рассказывала что reporting (практически любое отображение информации) надо делать не DDDшными средствами.


IB написал не один пост, что DDDшными средствами вообще ничего делать нельзя. Его я и сам читаю, если лияно у тебя есть аргументы по которым любое отображение информации надо делать неDDDшными средствами излагай.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[12]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 28.05.09 09:31
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Чем он ужасен? Что мешает отказаться от него в случаях когда он приносит неудобства? Каким образом

он привязан к рич модели?

Z>IB написал не один пост, что DDDшными средствами вообще ничего делать нельзя. Его я и сам читаю, если лично у тебя есть аргументы по которым любое отображение информации надо делать неDDDшными средствами излагай.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[8]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 28.05.09 10:05
Оценка: +1
Здравствуйте, IB, Вы писали:

GZ>>Organizes business logic by procedures where each procedure handles a single request from the presentation.

IB>Какое-то странное определение, ограничивающие Transaction Script презентацией, типа логики не может быть вообще.
+1
GZ>>Первое что бросается в глаза для Domain Model — both behavior and data. Чудненько и прекрасно. Очень похоже на Rich, если бы не абстрактный object model под которым можно понимать все что угодно.
IB>Это ты уже спекуляциями начинаешь заниматься — гаданием по Фаулеру, что же он имел ввиду.
Ну а что еще остается если изначально введеная им терминология неверна и алогична.

GZ>> Впрочем он никогда и не скрывал, что Anemic — это смесь Domain Model и Transaciton Script.

IB>Единственное что он говорил по этому поводу — "Какой кошмар, это же почти Transaction Script, это не ООП, а процедурное программирование" (С)
+1

GZ>>Я говорил именно об инстанцировании.

IB>А я об использовании.
Фраза вырванная из контекста — теряет смысл и может быть неверно истолкована.

GZ>>Смотря для кого?

IB>Для всего. У свойства дающего прямой доступ к данным стоит модификатор public.
Ну а если не стоит его публиковать?

GZ>>Но оно инкапсулировано относитель BLL, и изолировано от слоя еще выше.

IB>Каким боком?
Ты не влезешь в базу данных напрямки. Только опосредовано интерфейсу.

GZ>>Инкапсуляция не может быть измерена.

IB>Инкапсуляция отлично меряется, что подробно расписано у того же Меерса.
Не знал о такой метрике. Интересно послушать как.

GZ>>Использовать ACLService.CanEdit мы никаким боком использовать не можем, поскольку для выдачи решения нам не хватает информации.

IB>Мы можем прекрасным образом использовать ACLService.CanEdit передав ему всю необходимую информацию — либо самого parent-а,
Либо проявив недюженные экстрансенсорные способности изначально записать в контракт идентификатор парента. Но это изменение границ проекта на итерации. За это неплохо и по шапке получить.
IB>либо построив бизнес объект таким образом, чтобы вся необходимая информация уже была в нем.
А тут мы убиваем некоторый бонус Anemic. Бизнес-объект в первоначальном варианте был не нужен. Его вполне можно было бы и не поднимать.

IB>Разница лишь в том, что в отличии от Rich ты сделаешь это явно, причем именно там где полагается — при обращении к ACL, а в случае Rich, спустя какое-то время ты будешь сильно удивляться — какого хрена при обращении к MyObj.CanEdit он еще и к родителю лезет.

Угу. Пункт 3 преимуществ Anemic

GZ>> В случае Rich — нам достаточно переделать реализацию CanEdit,

IB>В стройной модели тоже самое.
Противоречишь.

GZ>>Так что лезвие бритвы — инкапсуляция выше, ресурсоемкость тоже.

IB>Я думаю — ты уже понял, где ошибался? =)
Нет. Вот чего не понял, того не понял.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: MozgC США http://nightcoder.livejournal.com
Дата: 28.05.09 10:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Приверженцы DDD и зирной модели предлагают все засунуть в объекты и проверять чуть ли не при каждом изменении полей. Но такая реализация очень плохо работает, особенно для сложных правил, где требуется задействовать несколько объектов.

G>Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.
Никто не мешает совмещать. Простейшие проверки можно сделать в сеттерах — тогда они будут срабатывать еще и прямо при редактировании в гриде или прибинденных полях редактирования — что по моему скромному мнению есть очень удобно.
Более сложные проверки можно вынести либо в метод Validate либо в какой-то ValidationService().
Re: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 10:26
Оценка: +1
Здравствуйте, GlebZ, Вы писали:

Супер, я давно хотел такое написать, а то реально получаеться что толчеться вода в ступе.

Тока в конце написал бы что последнее вермя (не лет ) использую рич модель.

Кстати слегка коробит от термина "толстая модель"...
А тут я живу и пишу...
Re[12]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 11:37
Оценка: :)
Здравствуйте, Ziaw, Вы писали:

Z>IB написал не один пост, что DDDшными средствами вообще ничего делать нельзя.

Минуточку
Во-первых я про DDD вообще ни слова.
А во-вторых, я ни где не говорил что "нельзя", наоборот, можно все. Порой только диву даешься, какой причудливый код работает. Другое дело, что поддерживать и развивать такой код — вспотеешь.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[2]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 11:37
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Супер, я давно хотел такое написать, а то реально получаеться что толчеться вода в ступе.

Только не Иван Иванычь, а Сергей Петрович, не пароход, а два рубля и не выиграл, а проиграл.
То есть, как выясняется — все напутано.

MC>Кстати слегка коробит от термина "толстая модель"...

Прально, потому что она жирная..
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[9]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 11:37
Оценка: +1
Здравствуйте, GlebZ, Вы писали:

IB>>Для всего. У свойства дающего прямой доступ к данным стоит модификатор public.

GZ>Ну а если не стоит его публиковать?
Рано или поздно все равно появится дополнительный сценарий, который потребует доступа к этому полю.

GZ>Ты не влезешь в базу данных напрямки. Только опосредовано интерфейсу.

Это всегда так, при любой модели.

GZ>Не знал о такой метрике. Интересно послушать как.

Почитай Меерса, в кратце — количество кода, которое потенциально может быть затронуто, при изменении объекта.

GZ>Либо проявив недюженные экстрансенсорные способности изначально записать в контракт идентификатор парента.

Никакой экстрасенсорики не надо. Вполне логично, что изменение требований безопасности потребовало изменения контракта метода, который эту безопасность осуществляет.

GZ>А тут мы убиваем некоторый бонус Anemic. Бизнес-объект в первоначальном варианте был не нужен. Его вполне можно было бы и не поднимать.

Нужен, ты же не одно поле поднимаешь.

GZ>Нет. Вот чего не понял, того не понял.

Стройная модель лучше, чем жирная, подходит для предложенного тобой изменения, а вовсе не наоборот.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 28.05.09 12:57
Оценка:
Здравствуйте, IB, Вы писали:

IB>>>Для всего. У свойства дающего прямой доступ к данным стоит модификатор public.

GZ>>Ну а если не стоит его публиковать?
IB>Рано или поздно все равно появится дополнительный сценарий, который потребует доступа к этому полю.
Могут появиться. А могут и не появиться. Зачем заниматься предварительной оптимизацией.

IB>Почитай Меерса, в кратце — количество кода, которое потенциально может быть затронуто, при изменении объекта.

Это не мера измерения. В основном измеряют цикломатическую сложность, coupling и cohesion. Для последних есть большое кол-во подвидов. Верная инкапсуляция, это всего лишь инструмент для оптимального coupling и cohesion.

GZ>>Либо проявив недюженные экстрансенсорные способности изначально записать в контракт идентификатор парента.

IB>Никакой экстрасенсорики не надо. Вполне логично, что изменение требований безопасности потребовало изменения контракта метода, который эту безопасность осуществляет.
Ну, о чем и говорилось. И соответвенно, как минимум во все методы вызывающие данный метод.

GZ>>А тут мы убиваем некоторый бонус Anemic. Бизнес-объект в первоначальном варианте был не нужен. Его вполне можно было бы и не поднимать.

IB>Нужен, ты же не одно поле поднимаешь.
Почему? Если тебе для выполнения какого-то метода нужен только идентификатор, ты всегда отдаешь целый объект?

GZ>>Нет. Вот чего не понял, того не понял.

IB>Стройная модель лучше, чем жирная, подходит для предложенного тобой изменения, а вовсе не наоборот.
Опять?
Re: Anemic Domain Model vs Rich Domain Model
От: syrompe  
Дата: 28.05.09 14:01
Оценка:
+1
вот чего не хватает так это законченных примеров.
может в инете где-нить есть?
Re[11]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 14:01
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Могут появиться. А могут и не появиться. Зачем заниматься предварительной оптимизацией.

Она не предварительная.

GZ>Это не мера измерения.

А что же это?

GZ>В основном измеряют цикломатическую сложность, coupling и cohesion.

А не в основном?

GZ>Верная инкапсуляция, это всего лишь инструмент для оптимального coupling и cohesion.

Вот именно. Соответственно, если в случае одной инкапсуляции связность выше, значит инкапсуляция ниже, и наоборот.

GZ>Ну, о чем и говорилось. И соответвенно, как минимум во все методы вызывающие данный метод.

Это плохо? Еще раз — у тебя есть два варианта:
1. Изменить бизнес-объект таким образом, чтобы вся необходимая информация уже была в нем в момент вызова.
2. Явно передать всю необходимую информацию при вызове.
И оба эти варианта лучше чем неявное поднятие нового объекта в CanEdit
Собственно, есть и третий вариант — ты можешь проинжектить ACLService, сервисом работы с данными и опять-таки поднять неявно родительский объект в CanEdit, но так делать не стоит — это мало чем будет отличаться от жирной модели, просто лишний раз подтверждает, что стройная легко покрывает описанный тобой сценарий.

GZ>Почему? Если тебе для выполнения какого-то метода нужен только идентификатор, ты всегда отдаешь целый объект?

Я не про отдачу, а про то что в момент отдачи у тебя полюбому целый объект.

GZ>Опять?

Что опять?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 14:47
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Супер, я давно хотел такое написать, а то реально получаеться что толчеться вода в ступе.

IB>Только не Иван Иванычь, а Сергей Петрович, не пароход, а два рубля и не выиграл, а проиграл.
IB>То есть, как выясняется — все напутано.

Эм, ты щас про что?
А тут я живу и пишу...
Re[2]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 14:57
Оценка:
Здравствуйте, syrompe, Вы писали:

S>+1

S>вот чего не хватает так это законченных примеров.
S>может в инете где-нить есть?

Все есть причем и того и того, достаточно подыскать опенсорсную реализацию чего-то и там копать...

Для рич моделей есть очень хороший специально сделаный пример — DDD Sample. Несмотря на то что это сампл, там покрыты 90% всех ситуаций стандарного корпоративного приложения.
А тут я живу и пишу...
Re[4]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 15:01
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Эм, ты щас про что?

Про то что опысывая все это GlebZ, к сожалению много чего напутал и ясности не внес.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 15:17
Оценка: :)
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Эм, ты щас про что?

IB>Про то что опысывая все это GlebZ, к сожалению много чего напутал и ясности не внес.

Ыыы, ну так напиши свое понимание этих моделей. Название новго треда "Anemic Domain Model vs Rich Domain Model (версия IB)", ну а мы почитаем. А еще интерсно было бы "Anemic Domain Model vs Rich Domain Model (версия gandjustas)". Сорри если я не правильно идентифицировал самых разговорчивых анемистов...

Реально по вашим размазаным по всему форуму постам непонятно что вы отстаиваете...

Да и мож не будут появляться фразы типа:
G>Я их не выдумываю. Их выдумывают приверженцы DDD. Напрмер aggregation root — огромный костыль DDD, который не я придумал. Также недавно тут пробегала ссылка на статью, которая рассказывала что reporting (практически любое отображение информации) надо делать не DDDшными средствами.
Могу и твоих фраз поискать про метод Сейв и тому подобное.
А тут я живу и пишу...
Re[6]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 15:39
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Ыыы, ну так напиши свое понимание этих моделей.

Я уже давно написал.

MC>Реально по вашим размазаным по всему форуму постам непонятно что вы отстаиваете...

Какой вопрос интересует?

MC>Могу и твоих фраз поискать про метод Сейв и тому подобное.

Что тебе в моих постах не нравится?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 15:52
Оценка:
Здравствуйте, IB, Вы писали:

MC>>Могу и твоих фраз поискать про метод Сейв и тому подобное.

IB>Что тебе в моих постах не нравится?

То же что и в постах gandjustas, сорри, но вы оба не шарите в рич моделях , .
А тут я живу и пишу...
Re: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 28.05.09 15:57
Оценка: 2 (2) +2
Здравствуйте, GlebZ, Вы писали:

GZ>Преимущества Anemic:

GZ>1. Простота построения. Это большой плюс, ибо главная задача архитектора, реализация функциональности за меньшие деньги. 90 процентов решений, могут быть построены в данной модели и это будет на порядок дешевле.
GZ>2. Бизнес-объекты – отчуждаемы. В результате, бизнес-объект может быть спокойно пронесен от DAL, к фасаду и даже далее. Беспрепятсвенно и идентично сериализован/десериализован между физическими слоями. В большинстве, бизнес-объект как бизнес-сущность не меняется при переносе между слоями.
GZ>3. Прогнозируемость и управляемость вплоть до DAL. Что под этим понимается. В случае, если вы ворочаете большими объемами данных, в Anemic вам проще управлять запросами к базе данных, чем в Rich. База данных была и остается самой тяжелой частью бизнес приложений. Оптимизация в основном достигается за счет повышения эффективности работы с базой данных(и зачастую не обычным редактирование SQL). В Anemic, вы спокойно можете провести тот, или иной сценарий через соседний сервис, который будет работать именно над этом тяжелым сценарием. В Rich — проблема как с прогнозом результирующего запроса, и с его оптимизацией.
GZ>4. Бизнес-объект проще управлять объектами, которые еще не полностью в валидированном состоянии. В Rich – наличие валидаторов обязывает держать валидированное состояние. Что иногда выливается в проблемы(например, когда объект только что создан, не имеет идентификатора, и не имеет тех, или иных ссылок). Во многом, бизнес-объект больше похож на данные, чем на объект в стиле объектного программирования.

Хотел бы подвергнуть сомнению все эти пункты:
1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;
2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае. Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;
3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;
4) Постоянная валидность бизнес-объектов и RDM -- совершенно не связанные между собой аспекты, в случае ADM точно так же можно наложить ограничение постоянной валидности. К тому же современные средства валидации бизнес-объектов поддерживают несколько степеней валидности, в зависимости от контекста.

GZ>Показания к использованию.

GZ>Во многом, IMHO, но…. Если вы ворочаете большими данными, то Anemic по любому. Если ваше приложение простое, то anemic. Если у вас большое количество сущностей, большее чем вы можете запомнить, и это не разбить на модули/компоненты/SOA, в которых будут бегать сотня программистов, то Rich. Но для Rich, нужно сразу запастись инструментальными средствами, типа Hibernate(у которого есть чудный кэш), и средства сериализации/десериализации. Это сгладит недостатки модели.

То, что Вы называете сглаживанием недостатков модели, я бы назвал просто правильным способом реализации RDM

P.S. Совсем недавно я писал развёрнутую статью на эту тему у себя в блоге, если любопытно:
http://javatoday.ru/2009/03/rich-domain-model/
Re[12]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 28.05.09 15:59
Оценка:
Здравствуйте, IB, Вы писали:

GZ>>Могут появиться. А могут и не появиться. Зачем заниматься предварительной оптимизацией.

IB>Она не предварительная.

GZ>>Это не мера измерения.

IB>А что же это?
Инструмент.

GZ>>В основном измеряют цикломатическую сложность, coupling и cohesion.

IB>А не в основном?
До хрена всего, а самое главное, разными способами. Только это для отдельной темы.

GZ>>Ну, о чем и говорилось. И соответвенно, как минимум во все методы вызывающие данный метод.

IB>Это плохо? Еще раз — у тебя есть два варианта:
IB>1. Изменить бизнес-объект таким образом, чтобы вся необходимая информация уже была в нем в момент вызова.
+-1 Только тогда это будет аналог Rich. Только значительно хуже. Ибо в Rich, можно спрятать дополнительную информацию за интерфейсом и загружать по мере надобности, а для некоторых сценариев вообще загружать вместе с основным объектом, в Anemic — он неделим.

IB>2. Явно передать всю необходимую информацию при вызове.

+1 Но проблема, что это надо передавать каждый раз в разных сценариях. Таким образом, ты и связываешь разные места с контрактом ACLService.CanEdit. Увеличиваешь cohesion.

IB>И оба эти варианта лучше чем неявное поднятие нового объекта в CanEdit

Ну наконец-то. Начинаю тебя понимать. Смотрим что было изначально:

инкапсуляция выше, ресурсоемкость тоже

Со вторым ты вроде согласен. А вот первое, тебе покоя не дает. Несмотря на конкретный пример.

IB>Собственно, есть и третий вариант — ты можешь проинжектить ACLService, сервисом работы с данными и опять-таки поднять неявно родительский объект в CanEdit, но так делать не стоит — это мало чем будет отличаться от жирной модели, просто лишний раз подтверждает, что стройная легко покрывает описанный тобой сценарий.

Это как раз чрезвычайно сильно изменяет модель относительно Rich. Тады ACLService придется понимать с каким именно объектом он имеет дело.

GZ>>Почему? Если тебе для выполнения какого-то метода нужен только идентификатор, ты всегда отдаешь целый объект?

IB>Я не про отдачу, а про то что в момент отдачи у тебя полюбому целый объект.
Нет. Это может быть список объектов которые можно редактировать. А может быть и список идентификаторов объектов которые можно редактировать.
Re[6]: Anemic Domain Model vs Rich Domain Model
От: Аноним  
Дата: 28.05.09 16:21
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Ыыы, ну так напиши свое понимание этих моделей. Название новго треда "Anemic Domain Model vs Rich Domain Model (версия IB)", ну а мы почитаем. А еще интерсно было бы "Anemic Domain Model vs Rich Domain Model (версия gandjustas)". Сорри если я не правильно идентифицировал самых разговорчивых анемистов...


MC>Реально по вашим размазаным по всему форуму постам непонятно что вы отстаиваете...


MC>Да и мож не будут появляться фразы типа:

G>>Я их не выдумываю. Их выдумывают приверженцы DDD. Напрмер aggregation root — огромный костыль DDD, который не я придумал. Также недавно тут пробегала ссылка на статью, которая рассказывала что reporting (практически любое отображение информации) надо делать не DDDшными средствами.
MC>Могу и твоих фраз поискать про метод Сейв и тому подобное.

Бгг, присоединяюсь )) Можно один топик с подтредом на каждого сильно разбирающегося в anemic и domain
Re[6]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 28.05.09 16:27
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Ыыы, ну так напиши свое понимание этих моделей. Название новго треда "Anemic Domain Model vs Rich Domain Model (версия IB)", ну а мы почитаем. А еще интерсно было бы "Anemic Domain Model vs Rich Domain Model (версия gandjustas)". Сорри если я не правильно идентифицировал самых разговорчивых анемистов...


MC>Реально по вашим размазаным по всему форуму постам непонятно что вы отстаиваете...


MC>Да и мож не будут появляться фразы типа:

G>>Я их не выдумываю. Их выдумывают приверженцы DDD. Напрмер aggregation root — огромный костыль DDD, который не я придумал. Также недавно тут пробегала ссылка на статью, которая рассказывала что reporting (практически любое отображение информации) надо делать не DDDшными средствами.
MC>Могу и твоих фраз поискать про метод Сейв и тому подобное.

Сорри, как-то не так отправилось.

Бгг, присоединяюсь )) Можно один топик с подтредом на каждого сильно разбирающегося в anemic и domain
Re[13]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 17:12
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Инструмент.

Инструмент — это инкапсуляция, и есть метрика правильности его применения.

GZ>+-1 Только тогда это будет аналог Rich.

Нет. Самый близкий аналог Rich — это третий способ.

GZ>Только значительно хуже. Ибо в Rich, можно спрятать дополнительную информацию за интерфейсом и загружать по мере надобности.

Значительно лучше. Это не дополнительная информация, это всегда необходимая информация.
Никто не собирается грузить родителя сразу, необходимая информация уже есть в дочернем, он самодостаточен, ему ничего не нужно.
Причем эта информация не является лишней, она необходима при каждой проверке доступа (и наверняка не только доступа, раз доступ на нее завязан).

GZ>+1 Но проблема, что это надо передавать каждый раз в разных сценариях.

Это не проблема. Это как раз хорошо. Я явно в каждом сценарии понимаю, что нужно и явно это передаю.
Причем забыть и не передать, я не могу — компилятор поправит. И явно передавая — четко понимаешь чего это стоит в каждом сценарии и каждый сценарий, при необходимости, ты можешь настроить отдельно, не трогая другие (например, в одном случае получая нужный объект из кеша, а в другом напрямую в обход всего, если это критично — инкапсуляция в действии (с)).
Если же у тебя все сценарии одинаковые, то написать обобщенный код тоже не rocket science, так что и с трудоемкостью проблем нет.

GZ>Таким образом, ты и связываешь разные места с контрактом ACLService.CanEdit.

А раньше они типа не были связаны, что ли?

GZ>Увеличиваешь cohesion.

Так этож хорошо.. Но на самом деле с когезией здесь ничего не происходит.

GZ>Ну наконец-то. Начинаю тебя понимать.

Похоже нет.

GZ>Со вторым ты вроде согласен. А вот первое, тебе покоя не дает. Несмотря на конкретный пример.

Конкретный пример показывает ровно обратное твоему утверждению, особенно если под ресурсоемкостью понимать стоимость дальнейшей поддержки, а не количество нажатий на клавиши для единоразового изменения логики CanEdit.

GZ>Это как раз чрезвычайно сильно изменяет модель относительно Rich.

Нет, не меняет.

GZ>Тады ACLService придется понимать с каким именно объектом он имеет дело.

Ровно в той же степени, что и для Rich.

GZ>Нет. Это может быть список объектов которые можно редактировать. А может быть и список идентификаторов объектов которые можно редактировать.

Из базы все равно приезжает список объектов, а не идентификаторов.
Мы уже победили, просто это еще не так заметно...
Re[8]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 17:15
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>То же что и в постах gandjustas,

Что конкретно?
Мы уже победили, просто это еще не так заметно...
Re[2]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 17:30
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>Хорошо приготовленная RDM в этом смысле превосходит ADM,

В этом смысле с хорошо приготовленной стройной моделью вообще мало что сравнится.

ЛИ>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.

То есть, уже никто, ничего, никуда не сериализует?

ЛИ>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

Составляет и еще какую, вне зависимоти от инструментария. Когда обращение к одному полю в UI, совершенно "прозрачно" вызывает по цепочке серию обращений к БД для поднятия списка — это конкретная проблема.

ЛИ>3) а значит можно в полной мере использовать преимущества RDM;

Какие?

ЛИ>То, что Вы называете сглаживанием недостатков модели, я бы назвал просто правильным способом реализации RDM

То есть, Rich == ORM?

ЛИ>P.S. Совсем недавно я писал развёрнутую статью на эту тему у себя в блоге, если любопытно:

ЛИ>http://javatoday.ru/2009/03/rich-domain-model/

Прикладная логика, по определению, формулируется в терминах навигации по графу прикладных объектов и его изменении.

Это неверное определение, отсюда и неверные выводы в твоей статье..
А на кешировании, Lazy Loading-е и прочих продвинутых инструментах, облегчающих работу с жирной моделью — уже только ленивый не потоптался.
Мы уже победили, просто это еще не так заметно...
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 19:49
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.

IB>То есть, уже никто, ничего, никуда не сериализует?
Я выдилил что именно никто и никуда не сериалзирует .


ЛИ>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

IB>Составляет и еще какую, вне зависимоти от инструментария. Когда обращение к одному полю в UI, совершенно "прозрачно" вызывает по цепочке серию обращений к БД для поднятия списка — это конкретная проблема.

Ты сам отвечаеш на вопрос что именно мне не нравиться, вот например это не нравиться... Ну и откуда такие выводы? Сам придумал? У нас не бывает таких проблем.

Мы не биндим доменные обьекты прямо в УИ, все обращения контролируються... Так что у нас небывает непредвиденных сайдеффектов. Типа УИ чето решило поменять, а отвалилось в датаслое.
А тут я живу и пишу...
Re[4]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 28.05.09 22:02
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Я выдилил что именно никто и никуда не сериалзирует .

То есть, бизнес-объекты никогда и никуда не сериализуются?

MC>Ты сам отвечаеш на вопрос что именно мне не нравиться, вот например это не нравиться...

Это вообще мало кому нравится, но это факт.

MC>Ну и откуда такие выводы? Сам придумал?

Нет, в жирной модели подсмотрел.

MC>Мы не биндим доменные обьекты прямо в УИ, все обращения контролируються...

Кем и как? То есть, мало того, что в бизнес-объектах логика, так еще и вокруг накрутили, чтобы контролировать то, с чем бизнес-объект не справляется?
Мы уже победили, просто это еще не так заметно...
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 28.05.09 23:26
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Я выдилил что именно никто и никуда не сериалзирует .

IB>То есть, бизнес-объекты никогда и никуда не сериализуются?
У нас нет. Сериализация это такое же публичное АПИ. Для него есть контракты.

MC>>Ну и откуда такие выводы? Сам придумал?

IB>Нет, в жирной модели подсмотрел.
Смешно, ты подсматрел то чего нет. Тебе не кажеться что ситуация слегка глуповатая?

MC>>Мы не биндим доменные обьекты прямо в УИ, все обращения контролируються...

IB>Кем и как?
Програмистом. Код то не секретарка пишет.

IB>То есть, мало того, что в бизнес-объектах логика, так еще и вокруг накрутили,

Опять дето подглядел? Плаин ПОКО. Ни маркировочных атрибтов, ничего. Тока чистые методы и состояние — рай.

IB> чтобы контролировать то, с чем бизнес-объект не справляется?

А че бизнес обьект должен думать об УИ? Мы на него таких респонсибилитей вообще не вешаем.
А тут я живу и пишу...
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 29.05.09 00:49
Оценка: :)
Здравствуйте, IB, Вы писали:

IB>

IB>Прикладная логика, по определению, формулируется в терминах навигации по графу прикладных объектов и его изменении.

IB>Это неверное определение, отсюда и неверные выводы в твоей статье..

Во-первых, это не определение, а следствие из определения. Во-вторых, отсюда в статье не может быть неверных выводов, потому что это последний абзац статьи
Re[12]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 07:13
Оценка:
Здравствуйте, Sinix, Вы писали:


S>Не обижайтесь, но у вас какое-то идеализированное представление о проектировании систем — берём требования, реализуем и все щасливы. Нифига!

Это действительно так. Достаточно накаждом этапе (сбор требований-анализ-проектирование-реализация) подключать мозг.

S>Во-первых требования никогда не содержат полной информации о предметной области. Это отдельная тема, подробнее стоит почитать у апологетов DDD.

И что? Разве кто-то мешает изучать предметную область?

S>Во-вторых, требования заказчика не всегда бывают выполнимыми: их нужно прноверять.

Лушче всего это делать на этапе анализа.

S>В-третьих если вам потребуется взаимодействие с внешними системами, от вас потребуется громадная куча фич, которые очевидны из предметной области, но не указаны в требованиях.

См выше.

S>В-четвёртых у модели предметной области приоритет банально выше: она стабильнее, требования заказчика гарантированно не могут выйти за пределы предметной области (точнее, могут захватить другую предметную область, но это другой разговор) и, самое главное, правила предметной области не зависят от хотелок заказчика/проектировщика и тем самым делает предсказуемым процесс разработки.

И что? Типа сначала надо модель предментной области забабахать, а потом думать как с ней программу написать.
Это дурацкий подход мягко говоря. В первую очередь на что надо ориентироваться — требования, предметная область вносит дополнительные ограничения не более того.

G>>Такие случаи требуют отдельного рассотрения так как размазывание логики между клиентом и сервером создает дополнительные проблмемы, которые не связаны с постановкой задачи.

G>>Я вообще склонен считать такие случаи паталогическими.
G>>Для поиска багов лучше тесты.

S>[ОФФТОП]

S>Про тесты: одно другого не отменяет. Лично мне куда проще саппортить такой код:
S>
S>void SomeMethod(string arg1, params int[] indexes)
S>{
S>  Code.NotNullOrEmpty(arg1, "arg1");
S>  Code.NotNull(indexes, "indexes");
S>  Code.GreaterThenOrEqual(indexes.Length, "indexes.Length", 5);
S>  Code.AssertState(CanDoSomeOperation, @"Some detailed exception message");

S>  // code goes here
S>}
S>


S>Сразу виден data contract + есть возможность отключать проверки по необходимости.

S>[/ОФФТОП]
Контракты — хорошо, только причем тут предметная область?
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 07:40
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


G>>Приверженцы DDD и зирной модели предлагают все засунуть в объекты и проверять чуть ли не при каждом изменении полей. Но такая реализация очень плохо работает, особенно для сложных правил, где требуется задействовать несколько объектов.

G>>Другой вариант делать все проверки при сохранении данных в БД, в таком случае проверка правил выноситстся в отдельные классы. Такой вариант предпочтительнее.
MC>Никто не мешает совмещать.
Я говореи не об удобстве, а о необходимости. Необходимы на самом деле только проверки при сохранении, для удобства можно хоть на каждый чих делать.
Хотя удобство тоже разное бывает. См ниже.

MC>Простейшие проверки можно сделать в сеттерах — тогда они будут срабатывать еще и прямо при редактировании в гриде или прибинденных полях редактирования — что по моему скромному мнению есть очень удобно.

Совсем неудобно. Как сделать client-side проверки в вебе при засовывании их в сеттеры?

MC>Более сложные проверки можно вынести либо в метод Validate либо в какой-то ValidationService().

Когда есть фреймворк валидации, то делать проверки в сеттерах бессмысленно (дублирование кода).
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 07:48
Оценка: 15 (1) :))
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, IB, Вы писали:


MC>>>Могу и твоих фраз поискать про метод Сейв и тому подобное.

IB>>Что тебе в моих постах не нравится?

MC>То же что и в постах gandjustas, сорри, но вы оба не шарите в рич моделях , .


О горе нам, как же мы с этим жить будем
Я еще на делфях создавал насколько возможно rich модель, затрахался сильно
Re[6]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 08:25
Оценка: 15 (1)
Здравствуйте, Mike Chaliy, Вы писали:

MC>У нас нет. Сериализация это такое же публичное АПИ. Для него есть контракты.

То есть, все таки сериализуется. Или все-таки нет? Ты не виляй ты прямо скажи.

MC>Смешно, ты подсматрел то чего нет. Тебе не кажеться что ситуация слегка глуповатая?

Меня эта ситуация пока что забавляет. С одной стороны у тебя все зашибись и проблем ты в упор не видишь, а с другой ничего конкретного сказать не можешь, на прямые вопросы не отвечаешь.
Вывод, в принципе очевиден, но словоблудие забавное.. =)

MC>Програмистом. Код то не секретарка пишет.

Какой код пишет программист?

MC>Опять дето подглядел?

У тебя вычитал..

MC> Плаин ПОКО. Ни маркировочных атрибтов, ничего. Тока чистые методы и состояние — рай.

Так как ты свои ПОКО сериализуешь?

MC>А че бизнес обьект должен думать об УИ?

Бизнес-объект вообще думать не должен.

MC>Мы на него таких респонсибилитей вообще не вешаем.

А какие вешаете?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[4]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 08:25
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>Во-первых, это не определение, а следствие из определения.

Если определение не верное, то следствие уж тем более.

ЛИ>Во-вторых, отсюда в статье не может быть неверных выводов, потому что это последний абзац статьи

Какая разница, какой это абзац, если это и есть ключевой момент твоей критики, остальное просто вода вокруг..
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[2]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 08:27
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>Хотел бы подвергнуть сомнению все эти пункты:

ЛИ>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;
Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения.


ЛИ>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.


Я бы архитектора выгнал сразу за такие слова.
Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб.

ЛИ>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся.

ЛИ>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.
Покажите пример кода, где по rich гораздо удобнее anemic.
Re[13]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 29.05.09 09:05
Оценка:
Здравствуйте, gandjustas, Вы писали:

S>>Не обижайтесь, но у вас какое-то идеализированное представление о проектировании систем — берём требования, реализуем и все щасливы. Нифига!

G>Это действительно так. Достаточно накаждом этапе (сбор требований-анализ-проектирование-реализация) подключать мозг.

Завидую — у нас реально разные ситуации. Мы в принципе говорим об одном и том же, просто вы не рассматриваете предметную область как нечто самостоятельное.

Я вам привёл самый обычный пример про невозможность проверок в 1 месте.
До примера вы писали

Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям

после:

Все что написано сильно зависит от предметной области и желаний заказчика.


Вы же сами пишете что предметная область всё-таки влияет на нюансы архитектуры приложения. Если я вырвал ваши слова из контекста — мои извинения, не так вас понял.



S>>Во-первых требования никогда не содержат полной информации о предметной области. Это отдельная тема, подробнее стоит почитать у апологетов DDD.
G>И что? Разве кто-то мешает изучать предметную область?
G>Лушче всего это делать на этапе анализа.

Ещё раз прошу — почитайте Эванса. Он классно расписал чем плох формальный подход к предметной области (и про анализ там тоже написано.) Ещё такое ощущение, что у вас разработка заканчивается с впариванием результатов заказчику — там такой подход конеш рулит.

S>>В-третьих если вам потребуется взаимодействие с внешними системами, от вас потребуется громадная куча фич, которые очевидны из предметной области, но не указаны в требованиях.

G>Лушче всего это делать на этапе анализа.
...
G>И что? Типа сначала надо модель предментной области забабахать, а потом думать как с ней программу написать.
G>Это дурацкий подход мягко говоря. В первую очередь на что надо ориентироваться — требования, предметная область вносит дополнительные ограничения не более того.

А вот здесь вы вообще неправы. Основное проектирование систенмы делается (если делается вообще) на первых итерациях.
А все проблемы о которых я говорю появляются позже, когда система уже сдана и эксплуатируется. И вот тогда вы огребаете проблем по-полной, потому что любой минорный фикс убивет к [censored] весь дизайн. Потому то вы поверили в достаточность требований, которые заведомо не содержат полной информации. Не люблю я подход "сделал как просили". Хреново смотрится когда ты получил деньги, а потом выставляешь заказчика идиотом.

Скажите, как вообще можно строить дизайн системы на основе функциональных требований? Они же описывают только внешний интерфейс системы. Всё что вы можете сделать — провести кластеризацию графа зависимостей и выделить компоненты по степени связности. Этот дизайн нифига не будет стабильным — любое новое требование перекроит все зависимости и дизайн, заточенный под конкретный набор юз-кейзов будет только мешать развивать систему.

Блин, я не знаю, как объяснять очевидные вещи... понимаете, модель предметной области — это не структура данных, не куча бумажек, и уж тем более не отчёт аналитика. Это грубо говоря общая модель, которая используется всеми и позволяет общаться на одном языке с неспециалистами, легко проверять корректность требований и предвидеть что потребуется дальше. Ну и в подарок получаете дизайн устойчивый к самым неожиданным требованиям.

Естественно, сразу строить _полную_ модель предметной области будет только полный идиот — т.к. штука в принципе бесконечная. Но использовать модель надо с самого начала проекта и не отступать от этого использования (опять было написано у Эванса). Поэтому ваши утверждения что "модель лучше использовать на этапе анализа" смотрятся весьма странно.


G>>>Для поиска багов лучше тесты.
S>>[ОФФТОП]
S>>Про тесты: одно другого не отменяет. Лично мне куда проще саппортить такой код:
S>>[/ОФФТОП]
G>Контракты — хорошо, только причем тут предметная область?

А почитайте всю цепочку — здесь предметная область не обсуждалась никак.
Re[14]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 09:49
Оценка: 12 (1)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


S>Я вам привёл самый обычный пример про невозможность проверок в 1 месте.

S>До примера вы писали
S>

S>Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям

S>после:
S>

S>Все что написано сильно зависит от предметной области и желаний заказчика.


S>Вы же сами пишете что предметная область всё-таки влияет на нюансы архитектуры приложения. Если я вырвал ваши слова из контекста — мои извинения, не так вас понял.

Естественно влияет — вносит дополнительные условия и ограничения в требования.

S>

S>>>Во-первых требования никогда не содержат полной информации о предметной области. Это отдельная тема, подробнее стоит почитать у апологетов DDD.
G>>И что? Разве кто-то мешает изучать предметную область?
G>>Лушче всего это делать на этапе анализа.

S>Ещё раз прошу — почитайте Эванса. Он классно расписал чем плох формальный подход к предметной области (и про анализ там тоже написано.)

Я его читал. Я предлагаю не рассматривать"предметную область" как вещь в себе.
Ведь в конченом итоге надо сделать приложение, которое полезно людям, а не модель некоторой предметной области.

S>Ещё такое ощущение, что у вас разработка заканчивается с впариванием результатов заказчику — там такой подход конеш рулит.

Не совсем "впариваением", но смысл именно такой — чтобы заказчик был доволен.

S>А все проблемы о которых я говорю появляются позже, когда система уже сдана и эксплуатируется. И вот тогда вы огребаете проблем по-полной, потому что любой минорный фикс убивет к [censored] весь дизайн. Потому то вы поверили в достаточность требований, которые заведомо не содержат полной информации. Не люблю я подход "сделал как просили". Хреново смотрится когда ты получил деньги, а потом выставляешь заказчика идиотом.

Это зависит от закачика и от менеджера.
Есть люди которые понимают, то рекая программа пишется раз и навсегда, что любая неучнеттая мелочь может оказаться критической.
Если заказчик и менеджер это понимаю, то получаются хорошие программы. (хотя если менеджер не понимает, то его уволить надо)
А бывают заказчики, которые хотят побыстрее, подешевле и побольше. С такимми действительно лучше работать по принципу "сделали как просили".

S>Скажите, как вообще можно строить дизайн системы на основе функциональных требований?

Рецепты давно известны: слабая связность и следовать принципам KISS и YAGNI.

S>Они же описывают только внешний интерфейс системы. Всё что вы можете сделать — провести кластеризацию графа зависимостей и выделить компоненты по степени связности. Этот дизайн нифига не будет стабильным — любое новое требование перекроит все зависимости и дизайн, заточенный под конкретный набор юз-кейзов будет только мешать развивать систему.

Далеко не так. Ведь у нас есть не только пожелания заказчика, а есть еще и требования от предметной области.
Стартовый набор требований обычно достаточно большой, чтобы большая часть системы оставалась стабильной при всех изменениях.

S>Блин, я не знаю, как объяснять очевидные вещи... понимаете, модель предметной области — это не структура данных, не куча бумажек, и уж тем более не отчёт аналитика. Это грубо говоря общая модель, которая используется всеми и позволяет общаться на одном языке с неспециалистами, легко проверять корректность требований и предвидеть что потребуется дальше.

Угу Ubiquitous Language, проходили уже. А толку от него? Ну поговорили вы со специалистами на их языке, сделали требования корректныим.
Как это на дизайн приложения повлияет.

S>Ну и в подарок получаете дизайн устойчивый к самым неожиданным требованиям.

Если бы все было так хорошо, как на словах, то все бы давно использовали DDD.
Вот только DDD начинает отсасывать даже тогда, когда просто требуется добавить нетривиальную экранную форму для каких-либо целей.

S>Естественно, сразу строить _полную_ модель предметной области будет только полный идиот — т.к. штука в принципе бесконечная. Но использовать модель надо с самого начала проекта и не отступать от этого использования (опять было написано у Эванса). Поэтому ваши утверждения что "модель лучше использовать на этапе анализа" смотрятся весьма странно.

Вот становится весело, когда новые требования не укладываются в модель.
Например была какая-то банальная торговая система, а тут потребовалось внести возможность резервирования и предзаказа.

ЗЫ. Чем больше кода у вас написано и чем большей степенью свзяности он обладает, тем тяжелее вносить изменения.
Заранее всех изменений не предугадаешь, лучше писать меньше кода и оставлять больше точек расширения.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 09:52
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>У нас нет. Сериализация это такое же публичное АПИ. Для него есть контракты.

IB>То есть, все таки сериализуется. Или все-таки нет? Ты не виляй ты прямо скажи.
Нет не сереализируеться.

MC>>Смешно, ты подсматрел то чего нет. Тебе не кажеться что ситуация слегка глуповатая?

IB>Меня эта ситуация пока что забавляет. С одной стороны у тебя все зашибись и проблем ты в упор не видишь, а с другой ничего конкретного сказать не можешь, на прямые вопросы не отвечаешь.
IB>Вывод, в принципе очевиден, но словоблудие забавное.. =)
Конкретное что? Я на любой конкретный вопрос по теме могу ответить. Я практикующий програмист.

MC>> Плаин ПОКО. Ни маркировочных атрибтов, ничего. Тока чистые методы и состояние — рай.

IB>Так как ты свои ПОКО сериализуешь?
Я их НЕ сериализирую.

MC>>Мы на него таких респонсибилитей вообще не вешаем.

IB>А какие вешаете?
Реализацию языка доменной модели.
А тут я живу и пишу...
Re[3]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 09:56
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

ЛИ>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;

G>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения.
Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры.

ЛИ>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.

G>Я бы архитектора выгнал сразу за такие слова.
G>Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб.
Имхо вы долбанетесь переделывать его в веб с сохранением архитектуры. Вы как-то раньше сами жаловались на это. Кроме того, бизнес-объекты даже в случае миграции в сторону web-клиента не передаются в UI -- там используются DTO, поэтому ничто не мешает бизнес-объектам быть rich; наоборот, часто это даже удобно.

ЛИ>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

G>Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся.
Речь об одном _физическом_ звене.

G>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.

G>Покажите пример кода, где по rich гораздо удобнее anemic.

Легко: ActiveRecord вам в руки. Для небольших проектов ну просто супер. Поюзайте ActiveWriter для простенького сайта или магазина, поймете, о чем я.
Только не надо заводить разговор о том, что Active Record -- это антипаттерн, потому что так кому-то приснилось.

Извините, если резко.
Re[8]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 10:12
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Нет не сереализируеться.

Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )

MC> Я на любой конкретный вопрос по теме могу ответить. Я практикующий програмист.

Пока не видно..

MC>Я их НЕ сериализирую.

Как они у тебя в базе оказываются?

MC>Реализацию языка доменной модели.

"С точки зрения банальной эрудиции, не каждый индивидуум способено лояльно игнорировать тенденции..." далее по тексту.
Спорим я больше умных слов знаю? Реализация — это не ответственность.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 10:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

ЛИ>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

G>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.
G>Покажите пример кода, где по rich гораздо удобнее anemic.

Вот можем начать с этого.

Rich
public void CreateOrder(number){
  var order = _orderFactory.Create(number);

  order.AddItem(product1, weight);
  order.AddItem(product2, weight);

  _orderRepository.Add(order);
}


Anemic
public void CreateOrder(number){
  validateOrderNumber(number);
  var total = calcualteTotal(weight1, weight2);
  validateIfTotalAcceptable(total);

  var order = new Order(){Number = number, Total = total};
  var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
  var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};

  _orderDAL.InsertOrder(order);
  _orderDAL.InsertOrderItem(item1);
  _orderDAL.InsertOrderItem(item2);
}
А тут я живу и пишу...
Re[4]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 10:18
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


ЛИ>>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;

G>>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения.
M>Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры.
В цифрах не могу, нету примера с жирной моделью и аналогичной ей стройной, чтобы сравнить.
Первое на что можно обратить внимание — необходимость согласовывать изменения в DTO и доменных объектах.
Второе — достачно сложное создание произвольных выборок.

ЛИ>>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.

G>>Я бы архитектора выгнал сразу за такие слова.
G>>Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб.
M>Имхо вы долбанетесь переделывать его в веб с сохранением архитектуры.
Дык в том задача архитектора, чтобы не долбанулись программисты.

M>Вы как-то раньше сами жаловались на это.

Нет. Я говорил что тупо написанное десктом приложение в веб переделать практически невозможно.
Если такой вариант возможен, то прилождение надо писать умно.

Как раз сейчас наблюдаю массовый переход на веб, тех кто еще год назад даже не думал о таком.

M>Кроме того, бизнес-объекты даже в случае миграции в сторону web-клиента не передаются в UI -- там используются DTO, поэтому ничто не мешает бизнес-объектам быть rich; наоборот, часто это даже удобно.

Ну это у кого как.
У меня примерно на 60% вьюх передаются Presentation Entity, а в остальных вполне хватает тех самых объектов, вытащенных из базы.
Причем часто Presentation Entity состоит из нескольких объектов, вытащенных из базы.

ЛИ>>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

G>>Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся.
M>Речь об одном _физическом_ звене.
Да, что-то промазал.

G>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.

G>>Покажите пример кода, где по rich гораздо удобнее anemic.

M>Легко: ActiveRecord вам в руки. Для небольших проектов ну просто супер. Поюзайте ActiveWriter для простенького сайта или магазина, поймете, о чем я.

Я как-то юзал ActiveRecord как раз для сайта, не заметил чтобы кода стало значительно меньше.
Кроме того все те же прооблемы с произвольными выборками.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 10:22
Оценка: +1
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Нет не сереализируеться.

IB>Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )
Мы в базу данных ничего не сереализируем. Туда наши обьекты мапяться. Для нас это делает тулинг(инфраструктура), например для базы данных это ОРМ тулы.
На другом сервере наши обьекты не оказываються. Там оказываються ДТО. Для ДТО у нас тоже есть тулинг типа AutoMapper.

MC>>Реализацию языка доменной модели.

IB>"С точки зрения банальной эрудиции, не каждый индивидуум способено лояльно игнорировать тенденции..." далее по тексту.
IB>Спорим я больше умных слов знаю? Реализация — это не ответственность.

Я же говорю читать надо, как я тебе еще могу сказать. Это стандарное понятиие в ДДД которое хрен оспориш. Если я тебе начну по-полочкам раскладывать ты опять отять буш выдергивать все из контекста и придираться к словам.
А тут я живу и пишу...
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 10:29
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, meowth, Вы писали:


M>>Здравствуйте, gandjustas, Вы писали:


ЛИ>>>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;

G>>>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения.
M>>Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры.
G>В цифрах не могу, нету примера с жирной моделью и аналогичной ей стройной, чтобы сравнить.
G>Первое на что можно обратить внимание — необходимость согласовывать изменения в DTO и доменных объектах.
Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

G>Второе — достачно сложное создание произвольных выборок.

Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.

Предположим что есть.
class Product{
}
class Image{
ProductId;
}
Для того чтобы получить флатен презентацию так или иначе придеться вводить промежуточное ДТО

ProductListItem{
Name
ImageSize,
ImageUrl
}

Решение и для рич моделей и для анмемичных идентичное.
А тут я живу и пишу...
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 29.05.09 10:50
Оценка:
Здравствуйте, IB, Вы писали:

IB>Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )


А в анемеичной модели с помощью колдовства сериализованные стандартными сериализатором объекты отлично понимают обработчики внешних файлов и другие сервера? Что с этими серверами становится при изменении модели?
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[4]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 10:51
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


ЛИ>>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

G>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.
G>>Покажите пример кода, где по rich гораздо удобнее anemic.

MC>Вот можем начать с этого.


MC>Rich

MC>
MC>public void CreateOrder(number){
MC>  var order = _orderFactory.Create(number);

MC>  order.AddItem(product1, weight);
MC>  order.AddItem(product2, weight);

MC>  _orderRepository.Add(order);
MC>}
MC>

Ага, еще код AddItem покажи, и валидации.
Кстати в какой момент она выполняется?

MC>Anemic

MC>
MC>public void CreateOrder(number){
MC>  validateOrderNumber(number);
MC>  var total = calcualteTotal(weight1, weight2);
MC>  validateIfTotalAcceptable(total);

MC>  var order = new Order(){Number = number, Total = total};
MC>  var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
MC>  var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};

MC>  _orderDAL.InsertOrder(order);
MC>  _orderDAL.InsertOrderItem(item1);
MC>  _orderDAL.InsertOrderItem(item2);
MC>}
MC>


Наверное имелось ввиду
public void CreateOrder(number)
{
  var order = new Order(){Number = number, Total = calcualteTotal(weight1, weight2)};
  var item1 = new Item(){Order = order, Product = product1, Weight = weight1};
  var item2 = new Item(){Order = order, Product = product2, Weight = weight2};

  _validationService.Validate(order);
  _orderRepository.Add(order);
}


А вообще на лице денормализация. Надо бы еще объяснить зачем она нужна и почему бы не поддерживать целостность триггерами в БД, если денормализация нужна.

Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 11:13
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Здравствуйте, gandjustas, Вы писали:


ЛИ>>>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

G>>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.
G>>>Покажите пример кода, где по rich гораздо удобнее anemic.

MC>>Вот можем начать с этого.


MC>>Rich

MC>>
MC>>public void CreateOrder(number){
MC>>  var order = _orderFactory.Create(number);

MC>>  order.AddItem(product1, weight);
MC>>  order.AddItem(product2, weight);

MC>>  _orderRepository.Add(order);
MC>>}
MC>>

G>Ага, еще код AddItem покажи, и валидации.
G>Кстати в какой момент она выполняется?

Зачем, ты же просил где лушче. Так вот за счет того что у нас есть енкапсуляция, код бизнес процесов получаеться максимально читабельным.

MC>>Anemic

MC>>
MC>>public void CreateOrder(number){
MC>>  validateOrderNumber(number);
MC>>  var total = calcualteTotal(weight1, weight2);
MC>>  validateIfTotalAcceptable(total);

MC>>  var order = new Order(){Number = number, Total = total};
MC>>  var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
MC>>  var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};

MC>>  _orderDAL.InsertOrder(order);
MC>>  _orderDAL.InsertOrderItem(item1);
MC>>  _orderDAL.InsertOrderItem(item2);
MC>>}
MC>>


G>Наверное имелось ввиду

G>
G>public void CreateOrder(number)
G>{
G>  var order = new Order(){Number = number, Total = calcualteTotal(weight1, weight2)};
G>  var item1 = new Item(){Order = order, Product = product1, Weight = weight1};
G>  var item2 = new Item(){Order = order, Product = product2, Weight = weight2};

G>  _validationService.Validate(order);
G>  _orderRepository.Add(order);
G>}
G>


нет мелось ввиду то что имелось,

1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?
2) ты поубирал ИД поля. Но вы же с ИБ орете что вам надо Order — Item для одного отдела, TradingPeriod — Item для другого. Как же это вы свзянанные обьекты сможете представить для двух отделов. Как вы сможете собрать из этого ДТО для веб сервиса, если оно все в коде зареференшено.
3) ты поубирал ИД поля. Это обозначает что у вас юзаеться ОРМ и тоже может юзаться лейзи лоад.
4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.

G>А вообще на лице денормализация. Надо бы еще объяснить зачем она нужна и почему бы не поддерживать целостность триггерами в БД, если денормализация нужна.

Ты конкретней, ты где нашел денормализацию?

Ты про Тотал? Почитай про архитектуры финансовых систем. Там никогда агрегатные результаты не считаються динамически. Если один раз ордер продался по цене 20.00089 денег, то даже когда поменяеються требования к округлению он всеравно должно остаться 20.00089.
Плюс номрализация Тотала не потдаеться юнит тестированию.

G>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?


Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так. Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?

В любом случае твой пример всеравно не читабельный. Попробуй его прочесть плаин текстом. Куча дублирования и мусора.
А тут я живу и пишу...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 11:17
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Мы в базу данных ничего не сереализируем.

А что же вы в нее, простите, делаете?

MC>Туда наши обьекты мапяться.

В чем отличие знаешь?

MC> Для нас это делает тулинг(инфраструктура), например для базы данных это ОРМ тулы.

Как именно?

MC>На другом сервере наши обьекты не оказываються. Там оказываються ДТО. Для ДТО у нас тоже есть тулинг типа AutoMapper.

Как этот DTO получается из объекта?

MC> Это стандарное понятиие в ДДД которое хрен оспориш.

Если бы ты еще понятия к месту формулировал, бы ло бы вообще замечательно.

MC> Если я тебе начну по-полочкам раскладывать ты опять отять буш выдергивать все из контекста и придираться к словам.

Где я к словам придирался? Ты еще ни на один вопрос внятно не ответил...
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 11:17
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>А в анемеичной модели с помощью колдовства сериализованные стандартными сериализатором объекты отлично понимают обработчики внешних файлов и другие сервера?

Это ты к чему?

Z> Что с этими серверами становится при изменении модели?

Ты о чем?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[6]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 11:17
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Мы этим гордимся,

Тем, что при изменении нужно поменять в четырех местах, а не в двух? Молодцы! =)

MC>у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере.

Легко у вас такая ситуация бывает — в модели поле удалили, а в DTO забыли, а у клиента на это поле была критичная логика завязана. В запросе пришел NULL — клиент лег.

MC>С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

Просто признайтесь, что вы любите двойную работу.

MC>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.

Для тебя это возможно будет новостью, но 95% задач современного приложения — это репортинг.
Отсюда делаем вывод о применимости жирной модели.

MC>Решение и для рич моделей и для анмемичных идентичное.

Когда есть LINQ необходимость в промежуточных DTO отпадает, можно все по месту построить, для стройной модели, разумеется.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[6]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 11:19
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, meowth, Вы писали:


M>>>Здравствуйте, gandjustas, Вы писали:


ЛИ>>>>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;

G>>>>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения.
M>>>Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры.
G>>В цифрах не могу, нету примера с жирной моделью и аналогичной ей стройной, чтобы сравнить.
G>>Первое на что можно обратить внимание — необходимость согласовывать изменения в DTO и доменных объектах.
MC>Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

Ведь гораздо легче вообще не иметь такой синхронизации.

G>>Второе — достачно сложное создание произвольных выборок.

MC>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.

Почему такая хорошая DDD заставляет выделять отдельное понятие репортинга? (на деле — любое отображение информации)

MC>Предположим что есть.

MC>class Product{
MC>}
MC>class Image{
MC> ProductId;
MC>}
MC>Для того чтобы получить флатен презентацию так или иначе придеться вводить промежуточное ДТО

MC>ProductListItem{

MC> Name
MC> ImageSize,
MC> ImageUrl
MC>}
Суть не в DTO, а в способах его получения.

MC>Решение и для рич моделей и для анмемичных идентичное.

Ну покажи полное решение для такого случая в rich, учитывая что надо получать далеко не все все товары, там есть пейджинг, видимость, выборка по категории итп. Для каждого товара существует куча картинок и надо получить первую.
Re[6]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 11:26
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Так вот за счет того что у нас есть енкапсуляция, код бизнес процесов получаеться максимально читабельным.

Код бизнес-процессов, за счет такой "енкапсуляции" получается малопредсказуемым и неочевидным.

MC>нет мелось ввиду то что имелось,

Тогда ты непонятно с чем споришь..

MC>В любом случае твой пример всеравно не читабельный.

Он гораздо понятнее чем твой.. )
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[11]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 11:30
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>> Для нас это делает тулинг(инфраструктура), например для базы данных это ОРМ тулы.

IB>Как именно?

_productRepository.Add(product);

Тебя интересует как работает Add это к ОРМ тулу твоего выбора. В НХибирнейт это Session.Save(obj);

MC>>На другом сервере наши обьекты не оказываються. Там оказываються ДТО. Для ДТО у нас тоже есть тулинг типа AutoMapper.

IB>Как этот DTO получается из объекта?

ProductDTO dto = Mapper.Map(product);

Тебя интересует как работает Mapэто к мапперу твоего выбора.

MC>> Это стандарное понятиие в ДДД которое хрен оспориш.

IB>Если бы ты еще понятия к месту формулировал, бы ло бы вообще замечательно.

И что там не к месту? Именно реализация этого языка это и есть респонсибилити. Хранит данные, не хранит, реализованно это методами или чем-то другим — это детали реализации. А респонсибилити это реалзиация языка.
Нарпимер для респонсибилити обьекта ордер это реализация языка по работе с оредорм. Например: Вычиление Тотала, Добовление айтемов, Маркировка временных айтемов, Преход в состояние А.
А тут я живу и пишу...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 11:35
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, IB, Вы писали:


IB>>Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )


Z>А в анемеичной модели с помощью колдовства сериализованные стандартными сериализатором объекты отлично понимают обработчики внешних файлов и другие сервера? Что с этими серверами становится при изменении модели?


Я уже спрашивал. Он считает что при изменении модели, публичный АПИ тоже должен поменяться .

Для них вообще поменять модель это что-то екстраординарное, обычно связанное с изменением модели данных, публичных АПИ, интерфесов пользователя и тому подобному...

Им не понять что такое поменять диометрально релейшеншип сущьностей и при этом не поменять ни хранилище и все вокруг .
А тут я живу и пишу...
Re[14]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 29.05.09 11:39
Оценка:
Здравствуйте, IB, Вы писали:

IB>Инструмент — это инкапсуляция, и есть метрика правильности его применения.

Ну наконец — то.

GZ>>+-1 Только тогда это будет аналог Rich.

IB>Нет. Самый близкий аналог Rich — это третий способ.
Вот ну офигенно оригинально. Разговор умного с суперумным.
— Модель плохая.
— Почему плохая? Вот же хорошее решение?
— Нет это не хорошее решение, потому что есть решение плохое.
— Почему нужно выбирать плохое решение?
— Потому что модель плохая, и для нее надо выбирать плохое решение.
Ну и что тут обсуждать?

GZ>>Только значительно хуже. Ибо в Rich, можно спрятать дополнительную информацию за интерфейсом и загружать по мере надобности.

IB>Значительно лучше. Это не дополнительная информация, это всегда необходимая информация.
Это аггрегируемая информация. Ибо на физическом уровне, доступ управляется набором идентификаторов связанных с объектом. Для того, чтобы получить реальный ACL — нужно ее просчитать по контексту пользователя и по объекту. По каждому чиху просчитывать информацию? Гениальное решение. Предлагаю занести в аналы природы. А если еще учесть что в экспорте/импорте этой информация вообще не нужна.
IB>Никто не собирается грузить родителя сразу, необходимая информация уже есть в дочернем, он самодостаточен, ему ничего не нужно.
IB>Причем эта информация не является лишней, она необходима при каждой проверке доступа (и наверняка не только доступа, раз доступ на нее завязан).
Ты читаешь что я пишу?

GZ>>+1 Но проблема, что это надо передавать каждый раз в разных сценариях.

IB>Это не проблема. Это как раз хорошо. Я явно в каждом сценарии понимаю, что нужно и явно это передаю.
Зачем???? Вот зачем тебе помнить чтобы солнце взошло, тебе нужно поднять сначало левый тумблем, а потом правый? Не проще ли на самом солнце кликнуть и не разбираться с проблемами бытия, орбит, и магнитных бурь.

IB>Причем забыть и не передать, я не могу — компилятор поправит.

Не поправит. У тебя интерфейс не изменяется, а только дополняется.
IB>И явно передавая — четко понимаешь чего это стоит в каждом сценарии и каждый сценарий, при необходимости, ты можешь настроить отдельно, не трогая другие (например, в одном случае получая нужный объект из кеша, а в другом напрямую в обход всего, если это критично — инкапсуляция в действии (с)).
А вот зачем? Весь смысл Rich, это то что ты абстрагируешься от БД. Хочешь накормить кошку, просто дай ей еды. Ежели хочешь помнить о том чтобы кишочках все это переваривалось, то даже преждевременное вскрытие тебе не поможет. Ты об этом узнаешь только постфактум, когда кал из кошки пойдет. Точно также и в больших приложениях. Пока реальных данных нет, ты не можешь сказать что оно работает с той, или иной степенью эффективности.

GZ>>Таким образом, ты и связываешь разные места с контрактом ACLService.CanEdit.

IB>А раньше они типа не были связаны, что ли?
Нет. В Rich — все места связаны с методом объекта. Объект и контекст пользователя, все что нужно для пользы дела. Все остальные проблемы, как зависимость от типа, можно решить в одном конкретном месте.

GZ>>Увеличиваешь cohesion.

IB>Так этож хорошо.. Но на самом деле с когезией здесь ничего не происходит.
Звиняюсь, coupling.

GZ>>Со вторым ты вроде согласен. А вот первое, тебе покоя не дает. Несмотря на конкретный пример.

IB>Конкретный пример показывает ровно обратное твоему утверждению, особенно если под ресурсоемкостью понимать стоимость дальнейшей поддержки, а не количество нажатий на клавиши для единоразового изменения логики CanEdit.
То, что можно изменить полиморфно поведение в одном месте существенно увеличивает поддержку? Абсолютно согласен. Ваще вопросов не возникает.

GZ>>Тады ACLService придется понимать с каким именно объектом он имеет дело.

IB>Ровно в той же степени, что и для Rich.
В Rich — строго наоборот. Объект решает как ему проверяться. Это большая разница.

GZ>>Нет. Это может быть список объектов которые можно редактировать. А может быть и список идентификаторов объектов которые можно редактировать.

IB>Из базы все равно приезжает список объектов, а не идентификаторов.
С чего ты решил?
Re[7]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 11:41
Оценка: +1
Здравствуйте, gandjustas и IB, Вы писали:

Нет, ребят, вы честно жжоте

Человек (Mike Chaliy) показывает вам на примере своего проекта, как оно работает -- что оно а)элегантно б)реально РАБОТАЕТ (это тоже важно) б)легко сопровождаемо в)не содержит тех проблем, которые вы пытаетесь отыскать в решении.

А вы по-прежнему продолжаете доказывать, что его решение плохое и полнится косяками и костылями -- не этими, так теми. Но при этом почему-то сами ставите ему вопрос, сами отвечаете, и в своем ответе находите недочеты, которые приписываете решению.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 11:48
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Мы этим гордимся,

IB>Тем, что при изменении нужно поменять в четырех местах, а не в двух? Молодцы! =)
Нам надо менять тока в том месте где надо.
1) Поменлась бизнес логика поменяли в моделе
2) Поменялся публичный АПИ, поменяли в ДТО
3) Потребовалось перелаяутить хранилище, со скрипом но и это сделали.

MC>>у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере.

IB>Легко у вас такая ситуация бывает — в модели поле удалили, а в DTO забыли, а у клиента на это поле была критичная логика завязана. В запросе пришел NULL — клиент лег.
Ну и кто дурак? У нас такого не быват. У нас публичный АПИ тестируеться.

MC>>С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

IB>Просто признайтесь, что вы любите двойную работу.


MC>>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.

IB>Для тебя это возможно будет новостью, но 95% задач современного приложения — это репортинг.
IB>Отсюда делаем вывод о применимости жирной модели.
Для меня это вообще не новость, у нас репортинг это инфраструктура к которой модель вообще не имеет отношения.
Обычно выбираеться из нескольких вариантов.
1) Для репортинга похожего по структуре на доменную модель, данные беруться из тех же маппингов что и доменная модель.
2) Для более сложного репортинга делаем свои маппинги.
3) Для совсем сложного пишем кастомный код.

Так как результатом репорта всерано являеться ДТО, то не изменение реализации, не изменение модели никак на результат не влияет, соотвевено клиенты живут себе долго и щасливо.

Если тебе хочеться сказать что типа ваша модель покрывает 5% кода приложения, а вот наша анемичная 95%(мне кажеться 40%), я с тобой вполне согласен. Для нас это не являеться камнем претконовения. Все ДТО у нас анемичны по определению.

MC>>Решение и для рич моделей и для анмемичных идентичное.

IB>Когда есть LINQ необходимость в промежуточных DTO отпадает, можно все по месту построить, для стройной модели, разумеется.
LINQ никто не отменял, с чего ты взял что мы не используем LINQ? У нас куча траверсинга на LINQ, репорты тож на LINQ...
А тут я живу и пишу...
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 11:57
Оценка:
Здравствуйте, gandjustas, Вы писали:


MC>>Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

G>
G>Ведь гораздо легче вообще не иметь такой синхронизации.
Гм, чем легче? Прототип набрасать да легче, а для потдерживаемого приложения вложения в эту синхронизацию не составляють и тысячных долей проекта....

G>>>Второе — достачно сложное создание произвольных выборок.

MC>>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.
G>
G>Почему такая хорошая DDD заставляет выделять отдельное понятие репортинга? (на деле — любое отображение информации)
Ым, потому что у нее респонсибилити другая... У репортинга своя, у модели другая...

G>Суть не в DTO, а в способах его получения.

И чем они отличаються? Если ты думаеш что мы пользуемся чем то секретным ты ошибаешся, все на виду...

MC>>Решение и для рич моделей и для анмемичных идентичное.

G>Ну покажи полное решение для такого случая в rich, учитывая что надо получать далеко не все все товары, там есть пейджинг, видимость, выборка по категории итп. Для каждого товара существует куча картинок и надо получить первую.


 (from p in Query() // Query возвращет IQueryable<Product>
        where p.Category.Contains("sdfsdf")
        select new ProductListItem(){
          Name = p.Name; 
          ImageUrl = p.Images.First().Url
        }).Take(10).ToList();


Чето типа того, писал прямо тут, могут быть ошибки.
В реальной реализации пейджинг, сортинг, фильтры находятсья в инфраструктуре.
А тут я живу и пишу...
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 12:04
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Так вот за счет того что у нас есть енкапсуляция, код бизнес процесов получаеться максимально читабельным.

IB>Код бизнес-процессов, за счет такой "енкапсуляции" получается малопредсказуемым и неочевидным.

И что там не очевидного? И что ты не можеш предсказать?

MC>>нет мелось ввиду то что имелось,

IB>Тогда ты непонятно с чем споришь..
MC>>В любом случае твой пример всеравно не читабельный.
IB>Он гораздо понятнее чем твой.. )

Сделал код более или мение читаебльным убрав необходимые фитчи, прикольно.

Так еще более читабельней... И респонсибилити ясна.

public CreateOrder(number){
}
А тут я живу и пишу...
Re[6]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 12:21
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Mike Chaliy, Вы писали:


MC>>>Здравствуйте, gandjustas, Вы писали:


ЛИ>>>>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

G>>>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.
G>>>>Покажите пример кода, где по rich гораздо удобнее anemic.

MC>>>Вот можем начать с этого.


MC>>>Rich

MC>>>
MC>>>public void CreateOrder(number){
MC>>>  var order = _orderFactory.Create(number);

MC>>>  order.AddItem(product1, weight);
MC>>>  order.AddItem(product2, weight);

MC>>>  _orderRepository.Add(order);
MC>>>}
MC>>>

G>>Ага, еще код AddItem покажи, и валидации.
G>>Кстати в какой момент она выполняется?

MC>Зачем, ты же просил где лушче. Так вот за счет того что у нас есть енкапсуляция, код бизнес процесов получаеться максимально читабельным.


MC>>>Anemic

MC>>>
MC>>>public void CreateOrder(number){
MC>>>  validateOrderNumber(number);
MC>>>  var total = calcualteTotal(weight1, weight2);
MC>>>  validateIfTotalAcceptable(total);

MC>>>  var order = new Order(){Number = number, Total = total};
MC>>>  var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
MC>>>  var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};

MC>>>  _orderDAL.InsertOrder(order);
MC>>>  _orderDAL.InsertOrderItem(item1);
MC>>>  _orderDAL.InsertOrderItem(item2);
MC>>>}
MC>>>


G>>Наверное имелось ввиду

G>>
G>>public void CreateOrder(number)
G>>{
G>>  var order = new Order(){Number = number, Total = calcualteTotal(weight1, weight2)};
G>>  var item1 = new Item(){Order = order, Product = product1, Weight = weight1};
G>>  var item2 = new Item(){Order = order, Product = product2, Weight = weight2};

G>>  _validationService.Validate(order);
G>>  _orderRepository.Add(order);
G>>}
G>>


MC>нет мелось ввиду то что имелось,

Тогда только могу констатировать факт что ты не умеешь рабоать со стройной моделью.

MC>1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?

Ну попробуй объясни. У меня нету ни одной тяжелой операции, которая вызывается неявно. А наносекнуды, затраченные на создания объектов роли не играют.

MC>2) ты поубирал ИД поля. Но вы же с ИБ орете что вам надо Order — Item для одного отдела, TradingPeriod — Item для другого. Как же это вы свзянанные обьекты сможете представить для двух отделов. Как вы сможете собрать из этого ДТО для веб сервиса, если оно все в коде зареференшено.

Нивопрос.
var qForDep1 = _ordersRepository.With(o => o.Items);
var qForDep2 = from item in _itemsRepository
               group item by item.Year;

Модель данных одна, представлений — скольтко угодно.

MC>3) ты поубирал ИД поля. Это обозначает что у вас юзаеться ОРМ и тоже может юзаться лейзи лоад.

Естественно ОРМ, а LL вообще нету (EF) или отключаем (Linq2SQL)

MC>4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.

Ничего не нарушил. Объекты не меняются пока не изменилась модель данных.

G>>А вообще на лице денормализация. Надо бы еще объяснить зачем она нужна и почему бы не поддерживать целостность триггерами в БД, если денормализация нужна.

MC>Ты конкретней, ты где нашел денормализацию?
Хранение total в order.

MC>Ты про Тотал? Почитай про архитектуры финансовых систем. Там никогда агрегатные результаты не считаються динамически. Если один раз ордер продался по цене 20.00089 денег, то даже когда поменяеються требования к округлению он всеравно должно остаться 20.00089.

Там же вес, причем ту архитектура финансовых систем?

MC>Плюс номрализация Тотала не потдаеться юнит тестированию.

Это повод вносить денормализацию?

G>>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?


MC>Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так.

Какой процесс? Там же создание заказа? Почему "создание заказа" считает Total, а не кто либо еще, кому оно надо?

MC>Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?

Потому что твой вариант таит больше проблем, чем ты можешь представить.
Нпапример пересчет тотала при добавлении\удалении\редактировании айтема.
Тебе понадобится поднять в память все айтемы для такой операции.
Очень дорогостоящее редактирование атема выйдет, если учесть что отправка ордера может и не произойти.


MC>В любом случае твой пример всеравно не читабельный. Попробуй его прочесть плаин текстом. Куча дублирования и мусора.

А ты не привел код AddItem.

Я кстати совершенно спокойно могу создать экстеншен метод AddItem и получить туже самую читаемоть что и у тебя.
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 12:30
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas и IB, Вы писали:


M>Нет, ребят, вы честно жжоте


M>Человек (Mike Chaliy) показывает вам на примере своего проекта, как оно работает -- что оно

Мы тут тоже все программированием занимаемся, если что

M>а)элегантно

Одинаково элегантно в любой модели. Anemic-Rich разницы не дает.

M>б)реально РАБОТАЕТ (это тоже важно)

Я свой кусок кода привел, который тоже реально работает.

M>б)легко сопровождаемо

На таком маленьком куске кода это незаметно будет. Anemic-Rich разницы не дает.

M>в)не содержит тех проблем, которые вы пытаетесь отыскать в решении.

На таком маленьком куске проблем тоже видно не будет. Хотя в том примере что Mike Chaliy привел проблемы таки есть, но они связаны с моделью опосредованно.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 12:39
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, meowth, Вы писали:


M>>Здравствуйте, gandjustas и IB, Вы писали:


M>>Нет, ребят, вы честно жжоте


M>>Человек (Mike Chaliy) показывает вам на примере своего проекта, как оно работает -- что оно

G>Мы тут тоже все программированием занимаемся, если что

M>>а)элегантно

G>Одинаково элегантно в любой модели. Anemic-Rich разницы не дает.

M>>б)реально РАБОТАЕТ (это тоже важно)

G>Я свой кусок кода привел, который тоже реально работает.

M>>б)легко сопровождаемо

G>На таком маленьком куске кода это незаметно будет. Anemic-Rich разницы не дает.

M>>в)не содержит тех проблем, которые вы пытаетесь отыскать в решении.

G>На таком маленьком куске проблем тоже видно не будет. Хотя в том примере что Mike Chaliy привел проблемы таки есть, но они связаны с моделью опосредованно.

Весь цимес в том, что он не доказывает и не собирается, что ваша модель -- плоха. Он говорит "ну, пользуйтесь anemic, раз вам в ней нормально. Но только имейте в виду, что Rich -- не такая ужасная, как вы думаете, а ее недостатки можно обойти, а не признавать неисправимыми"
А вы -- непременно пытаетесь это сделать по отношению к его модели: Rich model == evil под любым соусом.

Ладно, лучше я не буду спорить, потому что мне ближе его подход (особенно в плане чистоты бизнес-скриптов), и я буду необъективен. Уже, скорее всего
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 12:52
Оценка:
Здравствуйте, gandjustas, Вы писали:


MC>>1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?

G>Ну попробуй объясни. У меня нету ни одной тяжелой операции, которая вызывается неявно. А наносекнуды, затраченные на создания объектов роли не играют.

http://en.wikipedia.org/wiki/Fail-fast
В общем случае обозначает что в начале метода должны быть гарантированы рабочие инварианты. Например number == null, а он используеться для генерации текстового представления Айтама. Упс. NullRefrenceException. Это тока иллюстрация. С точки зрения безопасности это хорошо описано в Writing Secure Code, Second Edition

MC>>2) ты поубирал ИД поля. Но вы же с ИБ орете что вам надо Order — Item для одного отдела, TradingPeriod — Item для другого. Как же это вы свзянанные обьекты сможете представить для двух отделов. Как вы сможете собрать из этого ДТО для веб сервиса, если оно все в коде зареференшено.

G>Нивопрос.
G>
G>var qForDep1 = _ordersRepository.With(o => o.Items);
G>var qForDep2 = from item in _itemsRepository
G>               group item by item.Year;
G>

G>Модель данных одна, представлений — скольтко угодно.
И что? Пусть будет без ИД, и хотя у тебя теперь не ПОКО, ну да ладно. Это все равно значительно не облечило чтение.
Ну и ты не боишся что всю БД выгрузиш в память .
А еще ты не боишся что каието рефернсы будут нулл?

MC>>4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.

G>Ничего не нарушил. Объекты не меняются пока не изменилась модель данных.
У вас меняющиеся понятие СРП, в прошлый раз было тока хранение данных.

MC>>Ты про Тотал? Почитай про архитектуры финансовых систем. Там никогда агрегатные результаты не считаються динамически. Если один раз ордер продался по цене 20.00089 денег, то даже когда поменяеються требования к округлению он всеравно должно остаться 20.00089.

G> Там же вес, причем ту архитектура финансовых систем?
Это стандарный паттерн для любых вычислений, архитектура финансовых систем это там где про это тебе удобней всего будет почитать.

MC>>Плюс номрализация Тотала не потдаеться юнит тестированию.

G>Это повод вносить денормализацию?
Да

G>>>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?


MC>>Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так.

G>Какой процесс? Там же создание заказа? Почему "создание заказа" считает Total, а не кто либо еще, кому оно надо?
Потому что тотал должен быть сохранен единожды быв посчитан. Никто другой не должен самочинствовать и его считать. Кто-то другой может посчтиать какой-то свой тотал.

MC>>Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?

G>Потому что твой вариант таит больше проблем, чем ты можешь представить.
Конкретней, плз.
G>Нпапример пересчет тотала при добавлении\удалении\редактировании айтема.
Ессно у нас то рич модел, у нас не может получиться что тотал будет посчитан не правильно. И да пересчет тотала происходит при операциях с айтемами.

G>Тебе понадобится поднять в память все айтемы для такой операции.

G>Очень дорогостоящее редактирование атема выйдет, если учесть что отправка ордера может и не произойти.
Мы подымаем в память весь ордер со всеми айтемами. У нас это не вызвает проблем.

MC>>В любом случае твой пример всеравно не читабельный. Попробуй его прочесть плаин текстом. Куча дублирования и мусора.

G>А ты не привел код AddItem.
Зачем он тебе нужен если речь идет о читабельности этого метода. Я еще раз повторю, AddItem это черный ящик который гарантированно правильно добавит айтем и правильно изменит состояние ордера.

G>Я кстати совершенно спокойно могу создать экстеншен метод AddItem и получить туже самую читаемоть что и у тебя.

Добавив экстеншен метод у тебя получиться то о чем говорит ИБ. Ты не знаеш что делает AddItem. В рич моделе это решаеться скрытием состояния, рутагрегатами, боундариес, иммутабле валью обьектами и тому подобным. В анемик вы вообще никак не защищены от сайдеффектов. AddItem у вас может полезть в какуюто левую проперти, полезть в БД и тому подобное. Вобщемто экстеншен метод это будет самы главный антиагрумент.

Ты еше можеш и партиал использовать.

Собсно это был тока пример иллюстрирующий проблему, у AddItem может быть логика...
А тут я живу и пишу...
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 12:59
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:



MC>>>Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

G>>
G>>Ведь гораздо легче вообще не иметь такой синхронизации.
MC>Гм, чем легче? Прототип набрасать да легче, а для потдерживаемого приложения вложения в эту синхронизацию не составляють и тысячных долей проекта....
Ты не понял, у меня готовые приложения без такого рода DTO работают. Вообще.
И поддерживаются отлично.

G>>>>Второе — достачно сложное создание произвольных выборок.

MC>>>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.
G>>
G>>Почему такая хорошая DDD заставляет выделять отдельное понятие репортинга? (на деле — любое отображение информации)
MC>Ым, потому что у нее респонсибилити другая... У репортинга своя, у модели другая...
Странно, я anemic использую, ни разу не доходило до создания отдельной инфраструктуры репортинга (отображения).
Что тогда DDDшными методами делается?

G>>Суть не в DTO, а в способах его получения.

MC>И чем они отличаються? Если ты думаеш что мы пользуемся чем то секретным ты ошибаешся, все на виду...
Код в студию.

MC>>>Решение и для рич моделей и для анмемичных идентичное.

G>>Ну покажи полное решение для такого случая в rich, учитывая что надо получать далеко не все все товары, там есть пейджинг, видимость, выборка по категории итп. Для каждого товара существует куча картинок и надо получить первую.


MC>
MC> (from p in Query() // Query возвращет IQueryable<Product>
MC>        where p.Category.Contains("sdfsdf")
MC>        select new ProductListItem(){
MC>          Name = p.Name; 
MC>          ImageUrl = p.Images.First().Url
MC>        }).Take(10).ToList();
MC>

Ух ты, прям как у меня.
Тогда зачем вообще DDD? Aggregation roots всякие.
Где же Ubiquitous Language и читаемый Domain Expretом код?
Кстати, а кто вызывает показанный выше код?

MC>Чето типа того, писал прямо тут, могут быть ошибки.

MC>В реальной реализации пейджинг, сортинг, фильтры находятсья в инфраструктуре.
В какой инфраструктуре. Давай полный пример.
На входе есть products:IQueryable<Product>, который возвращает все записи. Показать надо первые 10 видимых, из категории X.
Какие будут классы, как распределена логика?
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 13:03
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, meowth, Вы писали:


M>>>Здравствуйте, gandjustas и IB, Вы писали:


M>>>Нет, ребят, вы честно жжоте


M>>>Человек (Mike Chaliy) показывает вам на примере своего проекта, как оно работает -- что оно

G>>Мы тут тоже все программированием занимаемся, если что

M>>>а)элегантно

G>>Одинаково элегантно в любой модели. Anemic-Rich разницы не дает.

M>>>б)реально РАБОТАЕТ (это тоже важно)

G>>Я свой кусок кода привел, который тоже реально работает.

M>>>б)легко сопровождаемо

G>>На таком маленьком куске кода это незаметно будет. Anemic-Rich разницы не дает.

M>>>в)не содержит тех проблем, которые вы пытаетесь отыскать в решении.

G>>На таком маленьком куске проблем тоже видно не будет. Хотя в том примере что Mike Chaliy привел проблемы таки есть, но они связаны с моделью опосредованно.

M>Весь цимес в том, что он не доказывает и не собирается, что ваша модель -- плоха. Он говорит "ну, пользуйтесь anemic, раз вам в ней нормально. Но только имейте в виду, что Rich -- не такая ужасная, как вы думаете, а ее недостатки можно обойти, а не признавать неисправимыми"

Тут есть некоторое отношение порядка, выражение для которого еще не придумано (и вряд ли будет придумиано когда-нибудь). Назовем его "лучше".
Так вот мы пытаемся показать что anemic лучше rich, а Mike Chaliy говорит что rich лучше anemic, причем неважно каким способом указывая недостатки одно из подходов или достоинства другого.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 13:05
Оценка:
Здравствуйте, gandjustas, Вы писали:

MC>>
MC>> (from p in Query() // Query возвращет IQueryable<Product>
MC>>        where p.Category.Contains("sdfsdf")
MC>>        select new ProductListItem(){
MC>>          Name = p.Name; 
MC>>          ImageUrl = p.Images.First().Url
MC>>        }).Take(10).ToList();
MC>>


G>На входе есть products:IQueryable<Product>, который возвращает все записи. Показать надо первые 10 видимых, из категории X.

G>Какие будут классы, как распределена логика?

Сорри, что лезу, но имхо все написано же:
p.Category.Contains("sdfsdf")... // из категории X
.. .Take(10) ... // первые 10
Re[2]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 29.05.09 13:06
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>Хотел бы подвергнуть сомнению все эти пункты:

ЛИ>1) Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;
Тут я бы проитерполировал сложность сопровождения в зависимости от количества сущностей. При большом количестве, RDM должен быть эффективней. Но RDM также приводит к более высоким требованиям по качеству архитектуры и качеству дизайна.

ЛИ>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае. Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

В паттернах Фаулера есть ключевое слово Enterprise о котором часто забывают. А это практически всегда означает, что клиенты как минимум хотят с кем-то, зачем-то интегрироваться. Поэтому переносимость нужна. А ежели объекты отчуждаемы, то это ващщее... Кроме того, даже на уровне потребления нельзя использовать голые классы. Иначе мы нарушаем изоляцию через фасад.
Насчет инструментов — я не возражал.

ЛИ>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

В том то и дело, что ADM все это нормально переваривает без костылей.

ЛИ>4) Постоянная валидность бизнес-объектов и RDM -- совершенно не связанные между собой аспекты, в случае ADM точно так же можно наложить ограничение постоянной валидности.

В ADM это как раз сделать очень сложно.

ЛИ>К тому же современные средства валидации бизнес-объектов поддерживают несколько степеней валидности, в зависимости от контекста.

Без возражений. Только вопрос что имелось ввиду под средствами?

ЛИ>То, что Вы называете сглаживанием недостатков модели, я бы назвал просто правильным способом реализации RDM

Немножко добавлю. Я — разработчик NET. В случае реализации ADM, я собираю приложения не пользуясь излишним инструментарием(ну ессно это не касается отчетов, OLAP и другой специализации). Это позволяет уменьшать сложность вхождения в проект, углубляет понимание самих процессов происходящих в решении. Я могу на коленке, собрать приложение любой степени сложности. И второе, что хотелось бы повторить. Я хочу не отвлекаться на правильность дизайна OOP. В реальности, реализация правильного дизайна OOP — весьма сложная штукенция. Можно заделать грабли.

ЛИ>P.S. Совсем недавно я писал развёрнутую статью на эту тему у себя в блоге, если любопытно:

ЛИ>http://javatoday.ru/2009/03/rich-domain-model/
Что-то уж очень страшное. Или я ваще ничего не понял, или одно из двух. У постановки может быть большое кол-во графов. Ну например, есть иерархия подчинения, типа отдел с директором, подчиненные подразделения и т.д. А есть проектные группы, которым эта иерархия ваще по барабану, так как там 3 чела с одного подразделения, 2 чела с другого. И у этих двух иерархий, независимые связи и некоторая ортогональная логика. Зачем мешать все в одном объекте? Не проще ли выделить некоторую логику в раздельные сервисы? Band of Four здря книжки писали?
Re[11]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 13:09
Оценка:
Здравствуйте, gandjustas, Вы писали:


M>>Весь цимес в том, что он не доказывает и не собирается, что ваша модель -- плоха. Он говорит "ну, пользуйтесь anemic, раз вам в ней нормально. Но только имейте в виду, что Rich -- не такая ужасная, как вы думаете, а ее недостатки можно обойти, а не признавать неисправимыми"

G>Тут есть некоторое отношение порядка, выражение для которого еще не придумано (и вряд ли будет придумиано когда-нибудь). Назовем его "лучше".
G>Так вот мы пытаемся показать что anemic лучше rich, а Mike Chaliy говорит что rich лучше anemic, причем неважно каким способом указывая недостатки одно из подходов или достоинства другого.

Покажите, где он говорит, что "лучше". Он говорит -- не хуже, потому что описанные вами ужос-нахи, которые неотвратимо настигнут всякого, осмелившегося поюзать rich, зачастую надуманны и оторваны от практики, а вы с эти спорите
причем где _вы_ говорите, что anemic лучше, я вижу -- например, в строчке выше; вы и не скрываете
Re[10]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 29.05.09 13:12
Оценка:
Здравствуйте, meowth, Вы писали:

M>А вы -- непременно пытаетесь это сделать по отношению к его модели: Rich model == evil под любым соусом.

Гы-гы. Собственно поэтому я и открыл этот флейм.
Re[15]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 13:16
Оценка: 15 (1)
Здравствуйте, GlebZ, Вы писали:

GZ>Ну наконец — то.

То есть, метрика таки есть. уже хорошо.

GZ>Ну и что тут обсуждать?

Сам не понимаю, я тебе про одно, а ты про другое.

GZ>Это аггрегируемая информация.

Да ну нет же.

GZ> Ибо на физическом уровне, доступ управляется набором идентификаторов связанных с объектом.

Так родительский идентификатор в объекте и так есть, тогда вообще ничего дополнительно делать не надо.

GZ> По каждому чиху просчитывать информацию? Гениальное решение.

По каждому чиху, вообще ничего делать не надо.

GZ>Ты читаешь что я пишу?

Похоже ты не читаешь, что я пишу.

GZ>Зачем????

За тем, что это важно, код понятнее и очевиднее.

GZ>Не проще ли на самом солнце кликнуть и не разбираться с проблемами бытия, орбит, и магнитных бурь.

Не проще, потому что когда понадобится щелкнуть этими тумблерами в обратном порядке, с одним ты ничего не сделаешь.

IB>>Причем забыть и не передать, я не могу — компилятор поправит.

GZ>Не поправит. У тебя интерфейс не изменяется, а только дополняется.
Ты серьезно считаешь, что если я изменю сигнатуру метода с CanEdit(id), на CanEdit(id, id), мне компилятор ничего не скажет?!!

GZ>А вот зачем? Весь смысл Rich, это то что ты абстрагируешься от БД.

Да затем, что не во всех сценариях нужно абстрагироваться — дырявая абстракция получается.

GZ>Нет. В Rich — все места связаны с методом объекта.

В Anemic тоже, только другого объекта. Вопрос не как, а по какому принципу.
В Rich — object cohesion, в Anemic — functional cohesion, и последнее — существенно лучше, с точки зрения поддрежки и изменения кода.

GZ> Объект и контекст пользователя, все что нужно для пользы дела. Все остальные проблемы, как зависимость от типа, можно решить в одном конкретном месте.

Нельзя, если типов больше одного, а вот в anemic как раз можно, вне зависимости от их количества.

GZ>Звиняюсь, coupling.

coupling как раз уменьшается.

GZ>То, что можно изменить полиморфно поведение в одном месте существенно увеличивает поддержку?

Во-первых не полиморфно, а во-вторых, существенно ухудшает, как только появляется дополнительный сценарий.

GZ>В Rich — строго наоборот. Объект решает как ему проверяться. Это большая разница.

Конечно, это один из основных косяков Rich, так как проверка зависит от контекста, значит объект должен знать обо всех контекстах.

GZ>С чего ты решил?

Со здравого смысла.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[12]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 13:16
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Тебя интересует как работает Add это к ОРМ тулу твоего выбора.

Меня интересует, как это работает у тебя.

MC>Тебя интересует как работает Mapэто к мапперу твоего выбора.

И это тоже.

MC>И что там не к месту?

Определение твое не к месту.

MC> Именно реализация этого языка это и есть респонсибилити.

Тогда ты вообще не о тех объектах.

MC>Нарпимер для респонсибилити обьекта ордер это реализация языка по работе с оредорм.

Так данные-то где?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[8]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 13:16
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Нам надо менять тока в том месте где надо.

Ну вот, а мы как раз про сценарий, когда везде надо. Как самый геморройный и самый часто встречающийся.

MC>Ну и кто дурак? У нас такого не быват. У нас публичный АПИ тестируеться.

А, то есть, твоя претензия к стройной модели сводится к тому, что там ничего не тестируется?
Вообщем, кончай заливать, что у вас все зашибись как изолировано.

MC>Для меня это вообще не новость, у нас репортинг это инфраструктура к которой модель вообще не имеет отношения.

А к чему же у вас тогда модель имеет отношение?

MC>Если тебе хочеться сказать что типа ваша модель покрывает 5% кода приложения, а вот наша анемичная 95%(мне кажеться 40%), я с тобой вполне согласен. Для нас это не являеться камнем претконовения. Все ДТО у нас анемичны по определению.

Отлично, так зачем вам тогда не DTO? Чтобы оставшиеся 5% выглядели красиво и правильно, по книжке?
Какую проблемы вы решаете, городя true domain model — чтобы ORM работал?

MC>LINQ никто не отменял, с чего ты взял что мы не используем LINQ? У нас куча траверсинга на LINQ, репорты тож на LINQ...

Ну правильно, у вас же там плоский DTO.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[8]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 13:16
Оценка:
Здравствуйте, meowth, Вы писали:

M>Человек (Mike Chaliy) показывает вам на примере своего проекта, как оно работает

В том, то и дело, что не показывает.

M>-- что оно а)элегантно б)реально РАБОТАЕТ (это тоже важно) б)легко сопровождаемо в)не содержит тех проблем, которые вы пытаетесь отыскать в решении.

Оно нифига не "элегантно", как выясняется, работать может вообще все, как я уже говорил, а про проблемы отдельный разговор. Тут вот походу выясняется, что свою красивую модель он вообще не использует, а использует повсюду DTO, а модель как раз для красоты и элегантности — понятно что проблем нет.

M> Но при этом почему-то сами ставите ему вопрос, сами отвечаете, и в своем ответе находите недочеты, которые приписываете решению.

Ну так он-то не отвечает, вот и приходится гадать.. =)
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[8]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 29.05.09 13:16
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>И что там не очевидного? И что ты не можеш предсказать?

Совершенно непонятно, что валидируется, как и с привлечением каких контекстов, непонятно, что из себя представляет продукт и откуда берется, ect...


MC>Так еще более читабельней... И респонсибилити ясна.

MC>public CreateOrder(number){
MC>}
Ну вот примерно так твой код и выглядит...
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 13:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Здравствуйте, gandjustas, Вы писали:



MC>>>>Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.

G>>>
G>>>Ведь гораздо легче вообще не иметь такой синхронизации.
MC>>Гм, чем легче? Прототип набрасать да легче, а для потдерживаемого приложения вложения в эту синхронизацию не составляють и тысячных долей проекта....
G>Ты не понял, у меня готовые приложения без такого рода DTO работают. Вообще.
G>И поддерживаются отлично.

Ну у меня тож есть приложения в которых уи на веб формах, логика-доступ к данным в одном слое, сотни класов менеджеров. И это все работает и потдерижвается. И что?

Ты же не можеш сравнить скорости добовления фитчеров. То что ты называеш рич моделью таковой не являеться. Соотвевенно у тебя просто нет опыта сравнить эти два подхода. Тебе с твоим подходом комфортней ок. У нас в команде рич модели это дефолтная архитектура. В тоже время рич модели не отменяют анемичных сущьностей. Всякие справочники, это просто инфа. Там нема логики. Для этого есть shared kernerl of value objects .

G>Странно, я anemic использую, ни разу не доходило до создания отдельной инфраструктуры репортинга (отображения).

G>Что тогда DDDшными методами делается?
Тока бизнес модели. Все построенно вокруг бизнес моделей. Если доменная область не позволяет построить рич модель, то естесвенный фалбек в анемичные модели. Соотвевенно иммутабилити обьектов, и соотвевенно возможность периспользовать сущьности в других слоях.
Рич модель идеальна когда стоимость реализации бизнес модели это самая большая часть бюджета. В ентрерпрайз приложениях это очень часто. Хотя уровень писателей ентерпрайз приложений обычно очень низок. А это приводит что люди думают в терминах хранилища данных. Что естевенно приводит к анемичным моделям, так как у таблиц нема поведения.

G>>>Суть не в DTO, а в способах его получения.

MC>>И чем они отличаються? Если ты думаеш что мы пользуемся чем то секретным ты ошибаешся, все на виду...
G>Код в студию.

 (from p in Query() // Query возвращет IQueryable<Product>
        where p.Category.Contains("sdfsdf")
        select new ProductListItem(){
          Name = p.Name; 
          ImageUrl = p.Images.First().Url
        }).Take(10).ToList();



MC>>>>Решение и для рич моделей и для анмемичных идентичное.

G>>>Ну покажи полное решение для такого случая в rich, учитывая что надо получать далеко не все все товары, там есть пейджинг, видимость, выборка по категории итп. Для каждого товара существует куча картинок и надо получить первую.

MC>>
MC>> (from p in Query() // Query возвращет IQueryable<Product>
MC>>        where p.Category.Contains("sdfsdf")
MC>>        select new ProductListItem(){
MC>>          Name = p.Name; 
MC>>          ImageUrl = p.Images.First().Url
MC>>        }).Take(10).ToList();
MC>>

G>Ух ты, прям как у меня.
G>Тогда зачем вообще DDD? Aggregation roots всякие.
Это репорт это не логика. DDD и всякие Aggregation roots нужны для постоения модели.

G>Где же Ubiquitous Language и читаемый Domain Expretом код?

В доменной модели.

G>Кстати, а кто вызывает показанный выше код?

Именно этот УИ. Метод MVC контроллера.

var query = new ListAllProductsQuery{};
var page = Get<IReportingService>().QueryPage(query);
return page.Results.Map(p => ProductListItemMapInstance.Map(p))


MC>>Чето типа того, писал прямо тут, могут быть ошибки.

MC>>В реальной реализации пейджинг, сортинг, фильтры находятсья в инфраструктуре.
G>В какой инфраструктуре. Давай полный пример.
G>На входе есть products:IQueryable<Product>, который возвращает все записи. Показать надо первые 10 видимых, из категории X.
G>Какие будут классы, как распределена логика?
Логики нет. Она тока в модели. Это по этому и денормализщация с тоталом.
Так настраиваеть query оьект. Это старая версия, щас более унифицированная версия...
var query = new ListAllProductsQuery
{
MaxResults = limit ?? 256
StartFrom = start,
SortFieldExpression = sort, // TODO Security hole, we should restrict select strings...
Direction = String.Equals(dir, "asc", StringComparison.OrdinalIgnoreCase)
? OrderDirection.Asc : OrderDirection.Desc
};

В ListAllProductsQuery доступна IQueryable НХибирнейта, весь пейджинг и фильтры там делаються там.
тож нужен пример?
IQueryable.Where().Take() и чето-там.
А тут я живу и пишу...
Re[13]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 13:30
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Тебя интересует как работает Add это к ОРМ тулу твоего выбора.

IB>Меня интересует, как это работает у тебя.
MC>>Тебя интересует как работает Mapэто к мапперу твоего выбора.
IB>И это тоже.
Сорри, я наверное туплю. Но я просто вызываю эти методы. Замени слова ЭТО на что-то конкретное.

MC>>И что там не к месту?

IB>Определение твое не к месту.
Ты его просто не понимаеш. Если бы понял, все было бы к месту. но судя по всему я не смогу обьяснить.

MC>> Именно реализация этого языка это и есть респонсибилити.

IB>Тогда ты вообще не о тех объектах.
Или ты не о тех. А ты о каких?

MC>>Нарпимер для респонсибилити обьекта ордер это реализация языка по работе с оредорм.

IB>Так данные-то где?
Поля обьекта. В его внутренней реализации. Хотя я не вижу особой разницы, может быть бег какой-то. Ты к чемуто клониш? Уж не к своему пониманию СРП, про то что хранение данных это уже достаточная респонсибилити?
А тут я живу и пишу...
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 13:36
Оценка: +1
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:



MC>>>1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?

G>>Ну попробуй объясни. У меня нету ни одной тяжелой операции, которая вызывается неявно. А наносекнуды, затраченные на создания объектов роли не играют.

MC>http://en.wikipedia.org/wiki/Fail-fast

MC>В общем случае обозначает что в начале метода должны быть гарантированы рабочие инварианты. Например number == null, а он используеться для генерации текстового представления Айтама. Упс. NullRefrenceException. Это тока иллюстрация. С точки зрения безопасности это хорошо описано в Writing Secure Code, Second Edition
К обсуждаемой теме отношения не имеет.
В реальном случае я бы Code Contracts вопользовался.

MC>И что? Пусть будет без ИД, и хотя у тебя теперь не ПОКО, ну да ладно. Это все равно значительно не облечило чтение.

К чему это?

MC>Ну и ты не боишся что всю БД выгрузиш в память .

нет, я LL принципиально не использую.

MC>А еще ты не боишся что каието рефернсы будут нулл?

Если они могут быть нулл, тогда будут проверки, если нет — то нет.

MC>>>4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.

G>>Ничего не нарушил. Объекты не меняются пока не изменилась модель данных.
MC>У вас меняющиеся понятие СРП, в прошлый раз было тока хранение данных.
А это и есть. Ведь есть productId — данные, а ссылка product только слегка упрощает работу.
Определение SRP одно, советую внимательно его изучить. Он является основопологающим принципом хоршего дизайна.

MC>>>Ты про Тотал? Почитай про архитектуры финансовых систем. Там никогда агрегатные результаты не считаються динамически. Если один раз ордер продался по цене 20.00089 денег, то даже когда поменяеються требования к округлению он всеравно должно остаться 20.00089.

G>> Там же вес, причем ту архитектура финансовых систем?
MC>Это стандарный паттерн для любых вычислений, архитектура финансовых систем это там где про это тебе удобней всего будет почитать.
Это ты сам придумал. Денормализацию в твоем слуцчае это никак не оправдывает.

MC>>>Плюс номрализация Тотала не потдаеться юнит тестированию.

G>>Это повод вносить денормализацию?
MC>Да
Надесь ты уже сосознал сколько проблем ты себе таким создал.
Можно пойти дальше, например есть у нас представление Order — Items, показанное выше и SalePeriod — Items, ты предложишь кешировать сумму по периоду тоже (учитывая доводы что ты приводил выше)? А где её кешировать?
А как после кучи таких кешировангий будет выглядеть код CUD для Item?

G>>>>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?


MC>>>Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так.

G>>Какой процесс? Там же создание заказа? Почему "создание заказа" считает Total, а не кто либо еще, кому оно надо?
MC>Потому что тотал должен быть сохранен единожды быв посчитан. Никто другой не должен самочинствовать и его считать. Кто-то другой может посчтиать какой-то свой тотал.

Ты расскажи зачем этот тотал нужен. Пока он никому не нужен его и считать не надо.
А то получается что ты придумал фигню, а теперь придумываешь оправдания.

Хочешь честно — давай исходные требования и разберем как их надо реализовывать.

MC>>>Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?

G>>Потому что твой вариант таит больше проблем, чем ты можешь представить.
MC>Конкретней, плз.
G>>Нпапример пересчет тотала при добавлении\удалении\редактировании айтема.
MC>Ессно у нас то рич модел, у нас не может получиться что тотал будет посчитан не правильно. И да пересчет тотала происходит при операциях с айтемами.
Уже начинаю плакать от смеха.
Таким образом мы получили пеессимизацию на ровном месте.
Кстати смотри выше SalePeriod — Items, как будешь выкручиваться?

G>>Тебе понадобится поднять в память все айтемы для такой операции.

G>>Очень дорогостоящее редактирование атема выйдет, если учесть что отправка ордера может и не произойти.
MC>Мы подымаем в память весь ордер со всеми айтемами. У нас это не вызвает проблем.
Браво, для редактирования одного айтема поднять в память полбазы — номальное явление для rich, ты это только что доказал.

MC>>>В любом случае твой пример всеравно не читабельный. Попробуй его прочесть плаин текстом. Куча дублирования и мусора.

G>>А ты не привел код AddItem.
MC>Зачем он тебе нужен если речь идет о читабельности этого метода. Я еще раз повторю, AddItem это черный ящик который гарантированно правильно добавит айтем и правильно изменит состояние ордера.
Ну не увиливай, приведи код. А то два куска неэвивалентны.

G>>Я кстати совершенно спокойно могу создать экстеншен метод AddItem и получить туже самую читаемоть что и у тебя.

MC>Добавив экстеншен метод у тебя получиться то о чем говорит ИБ.
о чем он говорит?

MC>Ты не знаеш что делает AddItem.

И ты не знаешь что делает AddItem в твоем случае. Это надо проверять тестами.

MC>В рич моделе это решаеться скрытием состояния, рутагрегатами, боундариес, иммутабле валью обьектами и тому подобным.

От кучи страшных слов гарантий не появится.

MC>В анемик вы вообще никак не защищены от сайдеффектов.

В rich вообще говоря тоже. Поэтому пишутся тесты.
Есдинственное отличие, что в anemic эти эффекты получить проще, но это проверяется тестами и программисты не заинектерованы писать неправильный код.

MC>AddItem у вас может полезть в какуюто левую проперти, полезть в БД и тому подобное. Вобщемто экстеншен метод это будет самы главный антиагрумент.

Твой AddItem может сделать тоже самое. Тебе все равно нужен способ доказать что он этого не делает.
Кстати в случае экстеншена у него меньше возможностей полезть во внутренее состояние объекта, поэтому экстеншены предпочтительнее. В Design Guidelines так и написано.

MC>Ты еше можеш и партиал использовать.

Партиал — обратный случай. Слишком много он может сделать с объектом.

MC>Собсно это был тока пример иллюстрирующий проблему, у AddItem может быть логика...

Тогда можно стразу идти стреляться. Потому что по коду программы станет невозможно определить что она делает.
В случае с extension кстати особо навороченную логик не засунешь. Экстеншену не откуда брать ссылку на SqlConnection например.
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 13:38
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


MC>>>
MC>>> (from p in Query() // Query возвращет IQueryable<Product>
MC>>>        where p.Category.Contains("sdfsdf")
MC>>>        select new ProductListItem(){
MC>>>          Name = p.Name; 
MC>>>          ImageUrl = p.Images.First().Url
MC>>>        }).Take(10).ToList();
MC>>>


G>>На входе есть products:IQueryable<Product>, который возвращает все записи. Показать надо первые 10 видимых, из категории X.

G>>Какие будут классы, как распределена логика?

M>Сорри, что лезу, но имхо все написано же:

M> p.Category.Contains("sdfsdf")... // из категории X
M> .. .Take(10) ... // первые 10
Угу, и этот код будет вызыватсья прямо из PL, весь DDD идет лесом.
Re[12]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 13:40
Оценка: 1 (1)
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:



M>>>Весь цимес в том, что он не доказывает и не собирается, что ваша модель -- плоха. Он говорит "ну, пользуйтесь anemic, раз вам в ней нормально. Но только имейте в виду, что Rich -- не такая ужасная, как вы думаете, а ее недостатки можно обойти, а не признавать неисправимыми"

G>>Тут есть некоторое отношение порядка, выражение для которого еще не придумано (и вряд ли будет придумиано когда-нибудь). Назовем его "лучше".
G>>Так вот мы пытаемся показать что anemic лучше rich, а Mike Chaliy говорит что rich лучше anemic, причем неважно каким способом указывая недостатки одно из подходов или достоинства другого.

M>Покажите, где он говорит, что "лучше". Он говорит -- не хуже, потому что описанные вами ужос-нахи, которые неотвратимо настигнут всякого, осмелившегося поюзать rich, зачастую надуманны и оторваны от практики, а вы с эти спорите

M>причем где _вы_ говорите, что anemic лучше, я вижу -- например, в строчке выше; вы и не скрываете

Еще раз "лучше" — название отношения порядка. Какие аргументы приводить для доказательства этого — разницы нету.
Все равно те кто пользуются rich не откажутся от него, как и пользователи anemic, а вот те кто еще не в курсе смогут для себя выводы сделать.
А то после прочтения фаулера у некоторых мозг отказывается самостоятельно работать.
Re[11]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 13:42
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>Сорри, что лезу, но имхо все написано же:

M>> p.Category.Contains("sdfsdf")... // из категории X
M>> .. .Take(10) ... // первые 10
G>Угу, и этот код будет вызыватсья прямо из PL, весь DDD идет лесом.

Mike же сказал, что это -- reporting, а там на DDD никто и не надеялся. Я сильно не прав?
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 13:52
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Нам надо менять тока в том месте где надо.

IB>Ну вот, а мы как раз про сценарий, когда везде надо. Как самый геморройный и самый часто встречающийся.
У нас практически не встречаеться. У нас публикуеться минимум, у нас это один из принципов. Поэтому если что-то надо добавить для УИ, то никто не будет этого менять, в сервисах и наоборот.
И вообще это очень зависит от приложения... Хз, мож у вас правило паблишить всю модель. У меня когда-то такое было. Клиент захотел что-бы базаданных была публичным АПИ.

MC>>Ну и кто дурак? У нас такого не быват. У нас публичный АПИ тестируеться.

IB>А, то есть, твоя претензия к стройной модели сводится к тому, что там ничего не тестируется?

Та не, ты привел какойто левый пример, я вообще ни слова притензий не сказал.
Про то что мы тестируем публичное АПИ, так это вобщемто вполне нормально, мы например вылавливали проблемы с сериализацией. Логично что зафиксировав АПИ мы заботимся о подписчиках.

IB>Вообщем, кончай заливать, что у вас все зашибись как изолировано.

Ну... Буш в Киеве заходи, покажу. Могу попробовать написать средства которыми мы помогам себе чтобы изоляция не порвалась...

MC>>Для меня это вообще не новость, у нас репортинг это инфраструктура к которой модель вообще не имеет отношения.

IB>А к чему же у вас тогда модель имеет отношение?
К бизнес модели. Репортинг это не более чем еще одно ридонли представление данных. А данные у нас меняються тока в модели.

MC>>Если тебе хочеться сказать что типа ваша модель покрывает 5% кода приложения, а вот наша анемичная 95%(мне кажеться 40%), я с тобой вполне согласен. Для нас это не являеться камнем претконовения. Все ДТО у нас анемичны по определению.

IB>Отлично, так зачем вам тогда не DTO? Чтобы оставшиеся 5% выглядели красиво и правильно, по книжке?

1) У нас модель самая дорагая часть. От этих процесов зависят деньги.
2) Мы выбираем самый подходящий инструмент. Если для нашей модели лучше рич, то почему не рич? Мы же не враги себе. Если для справочников/реопортов/контрактов нужно анемик, тю, знач анемик.

Книги тут вообще не причем. Я же не давлю что вот типа Еванс так сказал... Мы просто это используем. Нам нравиться. И я это рассказываю.

IB>Какую проблемы вы решаете, городя true domain model — чтобы ORM работал?

?? Еще раз, мы не городим, у нас код получаеться значительно лаконичней, лучше документирован, лучше для изменения бизнес логики. true domain model это набор практик, а не фреймворк. Его не надо городить. Ты просто его используеш и все.

MC>>LINQ никто не отменял, с чего ты взял что мы не используем LINQ? У нас куча траверсинга на LINQ, репорты тож на LINQ...

IB>Ну правильно, у вас же там плоский DTO.
У нас там такая же БД как и у тебя, соотвевенно ручные средства такие же точно как у вас.
А тут я живу и пишу...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 13:54
Оценка: :)
Здравствуйте, Mike Chaliy, Вы писали:

MC>Ну у меня тож есть приложения в которых уи на веб формах, логика-доступ к данным в одном слое, сотни класов менеджеров. И это все работает и потдерижвается. И что?

Медаль тебе.



MC>Ты же не можеш сравнить скорости добовления фитчеров. То что ты называеш рич моделью таковой не являеться.

ну так ты может свое определение Rich придумаешь? А то мы тут все пользуемся тем что фаулер нам рассказывает.

MC>Соотвевенно у тебя просто нет опыта сравнить эти два подхода.

У меня то как раз есть.
А вот у тебя в стройной модели опыта и нету.

G>>Странно, я anemic использую, ни разу не доходило до создания отдельной инфраструктуры репортинга (отображения).

G>>Что тогда DDDшными методами делается?
MC>Тока бизнес модели. Все построенно вокруг бизнес моделей. Если доменная область не позволяет построить рич модель, то естесвенный фалбек в анемичные модели. Соотвевенно иммутабилити обьектов, и соотвевенно возможность периспользовать сущьности в других слоях.
Приведи список фич, и покажи где задействовано DDD, а где anemic.

MC>Рич модель идеальна когда стоимость реализации бизнес модели это самая большая часть бюджета. В ентрерпрайз приложениях это очень часто. Хотя уровень писателей ентерпрайз приложений обычно очень низок. А это приводит что люди думают в терминах хранилища данных. Что естевенно приводит к анемичным моделям, так как у таблиц нема поведения.

Перефразирую: используя rich модель получите стоимость реализации модели в самую большую часть бюджета.

G>>Где же Ubiquitous Language и читаемый Domain Expretом код?

MC>В доменной модели.
А 95% — то самое отображение информации, забыл?
То есть самое DDD приложение только на 5% DDD? Остальное больше похоже на anemic или вообще без объектной модели?
Тогда и говорить не о чем.

G>>Кстати, а кто вызывает показанный выше код?

MC>Именно этот УИ. Метод MVC контроллера.

MC>
MC>var query = new ListAllProductsQuery{};
MC>var page = Get<IReportingService>().QueryPage(query);
MC>return page.Results.Map(p => ProductListItemMapInstance.Map(p)) //Однако в этом месте будет загрузка целого объекта p, а потом его маппинг
MC>

Прекрасно, см коммент.

MC>>>Чето типа того, писал прямо тут, могут быть ошибки.

MC>>>В реальной реализации пейджинг, сортинг, фильтры находятсья в инфраструктуре.
G>>В какой инфраструктуре. Давай полный пример.
G>>На входе есть products:IQueryable<Product>, который возвращает все записи. Показать надо первые 10 видимых, из категории X.
G>>Какие будут классы, как распределена логика?
MC>Логики нет. Она тока в модели. Это по этому и денормализщация с тоталом.
Как это логики нет? Фильтры, группировки — самая логика, которой реально 95% в любой программе.
Или по твоему логика, это только изменения данных, которые производятся не человеком?
Re[16]: Anemic Domain Model vs Rich Domain Model
От: GlebZ Россия  
Дата: 29.05.09 13:55
Оценка:
Здравствуйте, IB, Вы писали:

GZ>>Ну наконец — то.

IB>То есть, метрика таки есть. уже хорошо.
Неправильно. Метрики правильности его применения. Это несколько другое.

GZ>>Это аггрегируемая информация.

IB>Да ну нет же.
Ну надо же. Я же писал условия задачи, и тут оказывается что нет. Что ты в неагрегате собираешься хранить?

GZ>> Ибо на физическом уровне, доступ управляется набором идентификаторов связанных с объектом.

IB>Так родительский идентификатор в объекте и так есть, тогда вообще ничего дополнительно делать не надо.
Повторяю то что писал до этого. Если нам не хватает идентификатора, а нужно поднимать весь объект, то по ресурсоемкости задача равняется Rich. А вот по сопровождению — проигрывает.

IB>Не проще, потому что когда понадобится щелкнуть этими тумблерами в обратном порядке, с одним ты ничего не сделаешь.

Если тебе нужно закрутить солнце в другую сторону, найди другую кнопку на солнце. Иначе не факт, что при обратной последовательности действий солнце не упадет на землю, и вконец не придавит слонов которые ее держат.

IB>Ты серьезно считаешь, что если я изменю сигнатуру метода с CanEdit(id), на CanEdit(id, id), мне компилятор ничего не скажет?!!

Ввод новой сигнатуры не обозначает отмену старой которая используется для других объектов.

GZ>>А вот зачем? Весь смысл Rich, это то что ты абстрагируешься от БД.

IB>Да затем, что не во всех сценариях нужно абстрагироваться — дырявая абстракция получается.
Это уже вопрос ресурсоемкости а не дизайна.

GZ>>Нет. В Rich — все места связаны с методом объекта.

IB>В Anemic тоже, только другого объекта. Вопрос не как, а по какому принципу.
IB>В Rich — object cohesion, в Anemic — functional cohesion, и последнее — существенно лучше, с точки зрения поддрежки и изменения кода.
Что такое object cohesion?
Если тебе интересны подобные аналогии, то в Rich — распространен Data coupling, в Anemic — Control Coupling. Угадай, что лучше?

GZ>> Объект и контекст пользователя, все что нужно для пользы дела. Все остальные проблемы, как зависимость от типа, можно решить в одном конкретном месте.

IB>Нельзя, если типов больше одного, а вот в anemic как раз можно, вне зависимости от их количества.
Gang of Four — можешь подобрать любой способ. А для независимости от типа — нужно иметь слабоструктурированность. И это совершенно другая песня.

GZ>>То, что можно изменить полиморфно поведение в одном месте существенно увеличивает поддержку?

IB>Во-первых не полиморфно, а во-вторых, существенно ухудшает, как только появляется дополнительный сценарий.
Все, мило молчу. Тебе виднее.

GZ>>В Rich — строго наоборот. Объект решает как ему проверяться. Это большая разница.

IB>Конечно, это один из основных косяков Rich, так как проверка зависит от контекста, значит объект должен знать обо всех контекстах.
Опять. Если ты о контексте использования, то Gang of Four/
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 13:56
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, meowth, Вы писали:


M>>Человек (Mike Chaliy) показывает вам на примере своего проекта, как оно работает

IB>В том, то и дело, что не показывает.
Ну и ладно... В конце-то концов от меня не убудет. Разве что время потратил...

M>>-- что оно а)элегантно б)реально РАБОТАЕТ (это тоже важно) б)легко сопровождаемо в)не содержит тех проблем, которые вы пытаетесь отыскать в решении.

IB>Оно нифига не "элегантно", как выясняется, работать может вообще все, как я уже говорил, а про проблемы отдельный разговор. Тут вот походу выясняется, что свою красивую модель он вообще не использует, а использует повсюду DTO, а модель как раз для красоты и элегантности — понятно что проблем нет.

Хм, мы используем ее там где это оправдано. Ты же не используеш ТекстБокс как поле класса модели? Так и мы не используем анемик для реализации бизнес модели.

M>> Но при этом почему-то сами ставите ему вопрос, сами отвечаете, и в своем ответе находите недочеты, которые приписываете решению.

IB>Ну так он-то не отвечает, вот и приходится гадать.. =)

Пля, ну и где я не ответил? Дава конкретный вопрос где я не ответил.
А тут я живу и пишу...
Re[12]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 13:59
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>>>Сорри, что лезу, но имхо все написано же:

M>>> p.Category.Contains("sdfsdf")... // из категории X
M>>> .. .Take(10) ... // первые 10
G>>Угу, и этот код будет вызыватсья прямо из PL, весь DDD идет лесом.

M>Mike же сказал, что это -- reporting, а там на DDD никто и не надеялся.

Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting.
Ну что, господа архитекторы, где тут повторное использование кода?

M>Я сильно не прав?

Не, ты очень сильно прав. Даже неверное сильнее, чем хотелось бы.
Re[13]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 14:06
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>Mike же сказал, что это -- reporting, а там на DDD никто и не надеялся.

G>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting.
G>Ну что, господа архитекторы, где тут повторное использование кода?

А что именно не переиспользуеться?
Еще раз, в репортах ретрив информации. Ни клочка логики.
В модели изменение состояния.
А тут я живу и пишу...
Re[13]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 14:16
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>Mike же сказал, что это -- reporting, а там на DDD никто и не надеялся.

G>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting.

Хм, ты странно ведешь беседу.
По-твоему, для domain этот код плох, потому что он с слишком DTO-ориентирован, для репортинга плох, потому что не такой же, как для domain, хотя и лезет в domain, а для presentation layer я так и не понял почему плох, но у тебя он вызвал сильное отторжение.

G>разный код писать для работы с товарами категории X в domain и в reporting.

В основном -- нет, потому что AutoMapper отлично умеет мапить rich model на presentation DTO (или reporting items). Тот же самый код используется и для reporting'а, только потом из domain легким движением o2o mapper получается reporting DTO.

Однако может быть такое, что и надо. Но это -- редкая и ожидаемая фигня, потому что в репортинге все равно используются свои presentation envelopes aka DTO, и даже anеmic от них не спасет. (Блин, и мы опять обсуждаем тот + anemic, что там можно поднять domain model в UI. Тьфу!)

G>Ну что, господа архитекторы, где тут повторное использование кода?

Повторное использование будет там, где есть повторная парадигма. Был показан пример domain query, чего тебя не устраивает?

M>>Я сильно не прав?

G>Не, ты очень сильно прав. Даже неверное сильнее, чем хотелось бы.
Ну да же не знаю, что сказать. Неверное, я обратное доказывать не буду, потому что не собираюсь занимать позицию защищиющегося.
Re[11]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 14:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

MC>>Ты же не можеш сравнить скорости добовления фитчеров. То что ты называеш рич моделью таковой не являеться.

G>ну так ты может свое определение Rich придумаешь? А то мы тут все пользуемся тем что фаулер нам рассказывает.
Ну и чего у тебя тогда вопросы возникают? Файлер же не говорит что надо в домен засовывать фильры, кнопки сейв, сериализации или все то что вы тут описываете.


G>Приведи список фич, и покажи где задействовано DDD, а где anemic.


Рич
ДобавитьОрдер
ЗапаблишитьОрдер

Анемик
Показать Оредеры за такойто период (УИ, или репортты, или ДТО промапленые из модели)
Сделать доступным информацию про ордеры (ВебСервис, почти все операции ходтя в рич модель, а результат мапят в ДТО)

MC>>Рич модель идеальна когда стоимость реализации бизнес модели это самая большая часть бюджета. В ентрерпрайз приложениях это очень часто. Хотя уровень писателей ентерпрайз приложений обычно очень низок. А это приводит что люди думают в терминах хранилища данных. Что естевенно приводит к анемичным моделям, так как у таблиц нема поведения.

G>Перефразирую: используя rich модель получите стоимость реализации модели в самую большую часть бюджета.
смешно. Если у тебя бизнес логика это самое дешевое, то врядли тебе стоит нервничать.

G>>>Где же Ubiquitous Language и читаемый Domain Expretом код?

MC>>В доменной модели.
G> А 95% — то самое отображение информации, забыл?
95% это слова ИБ, я какнибуть погляжу статистику но что-то мне подсказывает что самая большая часть это УИ, потом домен, потом дто, потом инфраструктура.

G>То есть самое DDD приложение только на 5% DDD? Остальное больше похоже на anemic или вообще без объектной модели?

G>Тогда и говорить не о чем.
ОК, хотя я ответил ИБ на такой же точно вопрос.

G>>>Кстати, а кто вызывает показанный выше код?

ХЗ, я не знаю про какой ты код.

MC>>Именно этот УИ. Метод MVC контроллера.


MC>>
MC>>var query = new ListAllProductsQuery{};
MC>>var page = Get<IReportingService>().QueryPage(query);
MC>>return page.Results.Map(p => ProductListItemMapInstance.Map(p)) //Однако в этом месте будет загрузка целого объекта p, а потом его маппинг
MC>>

G>Прекрасно, см коммент.
И что? Это проблема?


MC>>Логики нет. Она тока в модели. Это по этому и денормализщация с тоталом.

G>Как это логики нет? Фильтры, группировки — самая логика, которой реально 95% в любой программе.
У нас это единожды написаный код. Мы просто периспользуем обьекты Query. Ессно что одинотипное фильтрование мы строим по метаданным.

G>Или по твоему логика, это только изменения данных, которые производятся не человеком?

Я про логику изменения состояния в модели данных. Обычно эти изменения инциализируються какараз человеком.
А тут я живу и пишу...
Re[14]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 14:23
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


M>>>Mike же сказал, что это -- reporting, а там на DDD никто и не надеялся.

G>>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting.
G>>Ну что, господа архитекторы, где тут повторное использование кода?

MC>А что именно не переиспользуеться?

MC>Еще раз, в репортах ретрив информации. Ни клочка логики.
MC>В модели изменение состояния.

Юзкейс из моего проекта. Только админ может видеть\редактировать\еще_что_то_делать с сущностями X, которые невидимы (Visible = false).
Короче для каждой операции надо накладывать условие выборки. У меня всо всех случаях (хоть репортиг, хоть что-то еще) делает это один и тот же код.
(На самом деле это делается для всех сущностей, у которых есть видимость, одним и тем же кодом)

В твоем случае придется два раза писать для reporting и domain.
Re[14]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 14:37
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>>>Mike же сказал, что это -- reporting, а там на DDD никто и не надеялся.

G>>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting.

M>Хм, ты странно ведешь беседу.

M>По-твоему, для domain этот код плох, потому что он с слишком DTO-ориентирован, для репортинга плох, потому что не такой же, как для domain, хотя и лезет в domain, а для presentation layer я так и не понял почему плох, но у тебя он вызвал сильное отторжение.
Это ты что-то придумал.

G>>разный код писать для работы с товарами категории X в domain и в reporting.

M>В основном -- нет, потому что AutoMapper отлично умеет мапить rich model на presentation DTO (или reporting items). Тот же самый код используется и для reporting'а, только потом из domain легким движением o2o mapper получается reporting DTO.
Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.
Кроме того, если нужны запросы с аггрегатными операциями, что придумаете?
Re[9]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 14:50
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Здравствуйте, gandjustas, Вы писали:



MC>>>>1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?

G>>>Ну попробуй объясни. У меня нету ни одной тяжелой операции, которая вызывается неявно. А наносекнуды, затраченные на создания объектов роли не играют.

MC>>http://en.wikipedia.org/wiki/Fail-fast

MC>>В общем случае обозначает что в начале метода должны быть гарантированы рабочие инварианты. Например number == null, а он используеться для генерации текстового представления Айтама. Упс. NullRefrenceException. Это тока иллюстрация. С точки зрения безопасности это хорошо описано в Writing Secure Code, Second Edition
G>К обсуждаемой теме отношения не имеет.
Имеет, попробуй сделать свой метод читабельным с учетом этого правила.
G>В реальном случае я бы Code Contracts вопользовался.
Гениально , особенно если учесть что мы пишем бизнес логику. Тогда уже Debug.Assert... Если не иронизировать, то в случае если number это может быть юзерский инпут(или пользование публичного АПИ) твои Code Contracts будут просто жестоко выглядеть , ты путаеш тулинг . Пустой number это не контракт метода, это инвалидная бизнес операция.

MC>>И что? Пусть будет без ИД, и хотя у тебя теперь не ПОКО, ну да ладно. Это все равно значительно не облечило чтение.

G>К чему это?
К тому что даже сделав референсы, читабельность метода значительно не улучшилась..

MC>>Ну и ты не боишся что всю БД выгрузиш в память .

G>нет, я LL принципиально не использую.
У Ордера свзяь с Айтемом, у Айтема с Периодом, У Айтема с Периодом. Пои идее у тебя должно выгрузить Ордер, Айтмы и Периодом, ну или хачить с зинтами. Но тогда хз когда и где полезут нуллы.

MC>>А еще ты не боишся что каието рефернсы будут нулл?

G>Если они могут быть нулл, тогда будут проверки, если нет — то нет.
А у нас не может быть нулов, в все твой нелюбимый агрегат рут.

MC>>>>4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.

G>>>Ничего не нарушил. Объекты не меняются пока не изменилась модель данных.
MC>>У вас меняющиеся понятие СРП, в прошлый раз было тока хранение данных.
G>А это и есть. Ведь есть productId — данные, а ссылка product только слегка упрощает работу.
G>Определение SRP одно, советую внимательно его изучить. Он является основопологающим принципом хоршего дизайна.
, Поржал, вы тут с ИБ практикуете уникальное понимание СРП и при этом ты говориш мне его изучать .

MC>>>>Ты про Тотал? Почитай про архитектуры финансовых систем. Там никогда агрегатные результаты не считаються динамически. Если один раз ордер продался по цене 20.00089 денег, то даже когда поменяеються требования к округлению он всеравно должно остаться 20.00089.

G>>> Там же вес, причем ту архитектура финансовых систем?
MC>>Это стандарный паттерн для любых вычислений, архитектура финансовых систем это там где про это тебе удобней всего будет почитать.
G>Это ты сам придумал. Денормализацию в твоем слуцчае это никак не оправдывает.
Ты дорастеш до этого... Правда потерянные нолики могут оказаться критическими, ну да ладно. Ты же сам себе на уме.

MC>>>>Плюс номрализация Тотала не потдаеться юнит тестированию.

G>>>Это повод вносить денормализацию?
MC>>Да
G>Надесь ты уже сосознал сколько проблем ты себе таким создал.
Это осознаное решение, основанное на своем и чужем опыте.

G>Можно пойти дальше, например есть у нас представление Order — Items, показанное выше и SalePeriod — Items, ты предложишь кешировать сумму по периоду тоже (учитывая доводы что ты приводил выше)? А где её кешировать?

Смотря чего ты добиваешся. В закрытом периоде SalePeriod вполне можно и кешировать, в открытом оно не имеет смысл.

G>А как после кучи таких кешировангий будет выглядеть код CUD для Item?

Хз, у нас такого кода нет.

G>>>>>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?

MC>>>>Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так.
G>>>Какой процесс? Там же создание заказа? Почему "создание заказа" считает Total, а не кто либо еще, кому оно надо?
MC>>Потому что тотал должен быть сохранен единожды быв посчитан. Никто другой не должен самочинствовать и его считать. Кто-то другой может посчтиать какой-то свой тотал.
G>
G>Ты расскажи зачем этот тотал нужен. Пока он никому не нужен его и считать не надо.
При изменении непроданного ордера должен пересчитаться тотал.

G>А то получается что ты придумал фигню, а теперь придумываешь оправдания.

Писец, что значит оправдания? Где оправдания? Это конкретная реаолизация с конкретными требованиями.
G>Хочешь честно — давай исходные требования и разберем как их надо реализовывать.
Выше. Я не представляю как ты будеш разбирать если у тебя нема представленя постороения таких систем...

MC>>>>Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?

G>>>Потому что твой вариант таит больше проблем, чем ты можешь представить.
MC>>Конкретней, плз.
G>>>Нпапример пересчет тотала при добавлении\удалении\редактировании айтема.
MC>>Ессно у нас то рич модел, у нас не может получиться что тотал будет посчитан не правильно. И да пересчет тотала происходит при операциях с айтемами.
G>Уже начинаю плакать от смеха.
G>Таким образом мы получили пеессимизацию на ровном месте.
G>Кстати смотри выше SalePeriod — Items, как будешь выкручиваться?
Выше.


G>>>Тебе понадобится поднять в память все айтемы для такой операции.

G>>>Очень дорогостоящее редактирование атема выйдет, если учесть что отправка ордера может и не произойти.
MC>>Мы подымаем в память весь ордер со всеми айтемами. У нас это не вызвает проблем.
G>Браво, для редактирования одного айтема поднять в память полбазы — номальное явление для rich, ты это только что доказал.
Да. Откуда ты взял пол базы? У нас есть понятие рут агрегата. Это обьект с четкими границами. У нас не бывает ситуаций когда неконтролированно подгружаеться что-то извне агрегата. И недозаполненый обьектов как у вас не бывает. У нас обьект всегда актуален.

MC>>>>В любом случае твой пример всеравно не читабельный. Попробуй его прочесть плаин текстом. Куча дублирования и мусора.

G>>>А ты не привел код AddItem.
MC>>Зачем он тебе нужен если речь идет о читабельности этого метода. Я еще раз повторю, AddItem это черный ящик который гарантированно правильно добавит айтем и правильно изменит состояние ордера.
G>Ну не увиливай, приведи код. А то два куска неэвивалентны.
Эквиваленты, полностью решают одну и туже задачу. И имеют идентичный результаты. Я не буду ничего приводить. Мне что скушно?

G>>>Я кстати совершенно спокойно могу создать экстеншен метод AddItem и получить туже самую читаемоть что и у тебя.

MC>>Добавив экстеншен метод у тебя получиться то о чем говорит ИБ.
G>о чем он говорит?
Что код говоно.

MC>>Ты не знаеш что делает AddItem.

G>И ты не знаешь что делает AddItem в твоем случае. Это надо проверять тестами.
Уже проверено. И гарантированно работает во всех инвариантах ордера. А твоя версия просто не может гарантировать инварианты.

MC>>В рич моделе это решаеться скрытием состояния, рутагрегатами, боундариес, иммутабле валью обьектами и тому подобным.

G>От кучи страшных слов гарантий не появится.
Появляеться. Как бы ты не сопротивлялся.

MC>>В анемик вы вообще никак не защищены от сайдеффектов.

G>В rich вообще говоря тоже. Поэтому пишутся тесты.
У нас запрещено выходить за приделы рут агрегатов, у нас запрещено выходить за приделы сервисов. На кажном уровне свои запреты. Причем для рут агрегатов это гарантируеться на компил тайме.
G>Есдинственное отличие, что в anemic эти эффекты получить проще, но это проверяется тестами и программисты не заинектерованы писать неправильный код.
Дава по пунктам.
Как ты получиш сокрытие данных в анемик? Иммутабле? Ты не можеш их пользовать у тебя Linq2Sql.
Как ты получиш рутагрегатамы? Вспомни про разные вью.
Как ты получиш боундариес? Тут проще в теории ничего сложного, но реально в рич моделях это на уровне практик, а в анемик про это даже не задумываються.

MC>>AddItem у вас может полезть в какуюто левую проперти, полезть в БД и тому подобное. Вобщемто экстеншен метод это будет самы главный антиагрумент.

G>Твой AddItem может сделать тоже самое. Тебе все равно нужен способ доказать что он этого не делает.
Выше
G>Кстати в случае экстеншена у него меньше возможностей полезть во внутренее состояние объекта, поэтому экстеншены предпочтительнее. В Design Guidelines так и написано.
Ссылку. Ты забыл у тебя анемик у тебя все состояние наружу.

MC>>Ты еше можеш и партиал использовать.

G>Партиал — обратный случай. Слишком много он может сделать с объектом.
Что можно больше сделать с обьектом у которого все открыто?

MC>>Собсно это был тока пример иллюстрирующий проблему, у AddItem может быть логика...

G>Тогда можно стразу идти стреляться. Потому что по коду программы станет невозможно определить что она делает.
Он добовляет айтем. Все просто.
G>В случае с extension кстати особо навороченную логик не засунешь. Экстеншену не откуда брать ссылку на SqlConnection например.
, супер агрумент.
А тут я живу и пишу...
Re[12]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 14:55
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


MC>>>Ты же не можеш сравнить скорости добовления фитчеров. То что ты называеш рич моделью таковой не являеться.

G>>ну так ты может свое определение Rich придумаешь? А то мы тут все пользуемся тем что фаулер нам рассказывает.
MC>Ну и чего у тебя тогда вопросы возникают? Файлер же не говорит что надо в домен засовывать фильры, кнопки сейв, сериализации или все то что вы тут описываете.


G>>Приведи список фич, и покажи где задействовано DDD, а где anemic.


MC>Рич

MC>ДобавитьОрдер
MC>ЗапаблишитьОрдер


MC>Анемик

MC>Показать Оредеры за такойто период (УИ, или репортты, или ДТО промапленые из модели)
А также:
Показать ордеры такого-то клиента.
Показать самые популярные товары
...

Короче ДобавитьОрдер, как уже выяснили в rich и anemic случае почти одинаково выглядят, наверное как и ЗапаблишитьОрдер.
Поэтому тему можно не продолжать. действительно при самом rich 95% получается вовсе даже anemic.

MC>>>Рич модель идеальна когда стоимость реализации бизнес модели это самая большая часть бюджета. В ентрерпрайз приложениях это очень часто. Хотя уровень писателей ентерпрайз приложений обычно очень низок. А это приводит что люди думают в терминах хранилища данных. Что естевенно приводит к анемичным моделям, так как у таблиц нема поведения.

G>>Перефразирую: используя rich модель получите стоимость реализации модели в самую большую часть бюджета.
MC> смешно. Если у тебя бизнес логика это самое дешевое, то врядли тебе стоит нервничать.
У меня на самом деле БЛ — всегда самая большая часть. Для меня логика — это то что лежит между разметкой UI и базой данных.
Ифраструктурная часть логики одинаковая для всех проектов, поэтому её писать не надо.

MC>>>Именно этот УИ. Метод MVC контроллера.


MC>>>
MC>>>var query = new ListAllProductsQuery{};
MC>>>var page = Get<IReportingService>().QueryPage(query);
MC>>>return page.Results.Map(p => ProductListItemMapInstance.Map(p)) //Однако в этом месте будет загрузка целого объекта p, а потом его маппинг
MC>>>

G>>Прекрасно, см коммент.
MC>И что? Это проблема?
Вообще то да.
Чтобы сформировать ProductListItem (три поля) тебе понадобится поднять в память весь product, весь список связанных Image, а только потом маппер сделает 3 поля.

MC>>>Логики нет. Она тока в модели. Это по этому и денормализщация с тоталом.

G>>Как это логики нет? Фильтры, группировки — самая логика, которой реально 95% в любой программе.
MC>У нас это единожды написаный код. Мы просто периспользуем обьекты Query. Ессно что одинотипное фильтрование мы строим по метаданным.
Это просто нету сложных выборок. Например как получить список заказов с суммой , если сумма не кешируется в самом заказе?
Метаданные отдыхают.
Re[15]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 14:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Юзкейс из моего проекта. Только админ может видеть\редактировать\еще_что_то_делать с сущностями X, которые невидимы (Visible = false).

G>Короче для каждой операции надо накладывать условие выборки. У меня всо всех случаях (хоть репортиг, хоть что-то еще) делает это один и тот же код.
G>(На самом деле это делается для всех сущностей, у которых есть видимость, одним и тем же кодом)

G>В твоем случае придется два раза писать для reporting и domain.


Я не вижу дублирования.

1) Первое у нас в продукте есть Multitenancy. Это когда в одной БД можут находиться несколько разных приложений (это мы економим на хосете моде). Реализвано приблизительно как в http://java.dzone.com/articles/introduction-hibernate-filters У нас аналогичное тока програмно. Мы не используем ХМЛ.
Фактически с фильтром приложение не видит ничего из того что ей не позволено.

2) Ну а второе, секурити тримминг это не респонсибилити модели. Этим может заниматься тока ендинтерфейс, ну или аппликейшен фасады. В домене вообще нема понятия Админа.
А тут я живу и пишу...
Re[13]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 29.05.09 15:08
Оценка:
Здравствуйте, gandjustas, Вы писали:


MC>>И что? Это проблема?

G>Вообще то да.
G>Чтобы сформировать ProductListItem (три поля) тебе понадобится поднять в память весь product, весь список связанных Image, а только потом маппер сделает 3 поля.
Если это станет проблемой, а оно не станет, как я говорил у нас кеши. Мы прикрутим кастомный репорт.

G>Это просто нету сложных выборок. Например как получить список заказов с суммой , если сумма не кешируется в самом заказе?

Незнаю, ты придумал себе проблему ты и решай. У нас суммы не кешируються. У нас они сохраняються.
А тут я живу и пишу...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 15:32
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Mike Chaliy, Вы писали:


MC>>>Здравствуйте, gandjustas, Вы писали:



MC>>>>>1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?

G>>>>Ну попробуй объясни. У меня нету ни одной тяжелой операции, которая вызывается неявно. А наносекнуды, затраченные на создания объектов роли не играют.

MC>>>http://en.wikipedia.org/wiki/Fail-fast

MC>>>В общем случае обозначает что в начале метода должны быть гарантированы рабочие инварианты. Например number == null, а он используеться для генерации текстового представления Айтама. Упс. NullRefrenceException. Это тока иллюстрация. С точки зрения безопасности это хорошо описано в Writing Secure Code, Second Edition
G>>К обсуждаемой теме отношения не имеет.
MC>Имеет, попробуй сделать свой метод читабельным с учетом этого правила.
тебе больше придраться не к чему?

G>>В реальном случае я бы Code Contracts вопользовался.

MC>Гениально , особенно если учесть что мы пишем бизнес логику. Тогда уже Debug.Assert... Если не иронизировать, то в случае если number это может быть юзерский инпут(или пользование публичного АПИ) твои Code Contracts будут просто жестоко выглядеть , ты путаеш тулинг . Пустой number это не контракт метода, это инвалидная бизнес операция.
Ты ни разу не пользовался контрактами чтоли?
Я поставлю контракт в createOrder, проверятель начнет ругаться в вызвающем методе, что может быть передан неправльный number, я вставлю контракт там, итд.
Так дойдет до PL, где я просто обязан буду вставить проверку на пустой намбер.

А перед сохранением вставлю код валидации объекта, чтобы гарантировано в базу неверная инфа не попала.

MC>>>И что? Пусть будет без ИД, и хотя у тебя теперь не ПОКО, ну да ладно. Это все равно значительно не облечило чтение.

G>>К чему это?
MC>К тому что даже сделав референсы, читабельность метода значительно не улучшилась..
Ну ты достал уже

public void CreateOrder(number)
{
  Contract.Requires(number != null);

  var order = new Order(){Number = number, Total = calcualteTotal(weight1, weight2)};
  order.AddItem(product1, weight1);
  order.AddItem(product2, weight2);

  _validationService.Validate(order);
  _orderRepository.Add(order);
}

AddItem — экстеншен метод, код которого я тебе не покажу.
Теперь гораздо интереснее.
Явный контракт позволяет статически проверки делать — очень гут.
Нету скрытой логики с calculateTotal внутри ордера — тоже прекрасно.

MC>>>Ну и ты не боишся что всю БД выгрузиш в память .

G>>нет, я LL принципиально не использую.
MC>У Ордера свзяь с Айтемом, у Айтема с Периодом, У Айтема с Периодом. Пои идее у тебя должно выгрузить Ордер, Айтмы и Периодом, ну или хачить с зинтами. Но тогда хз когда и где полезут нуллы.
Эта фраза похожа на заклинание вызова духов...

MC>>>А еще ты не боишся что каието рефернсы будут нулл?

G>>Если они могут быть нулл, тогда будут проверки, если нет — то нет.
MC>А у нас не может быть нулов, в все твой нелюбимый агрегат рут.
Это вам кто обеспечивает? Святой дух? Все равно ведь для этого код написан.

MC>>>>>4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.

G>>>>Ничего не нарушил. Объекты не меняются пока не изменилась модель данных.
MC>>>У вас меняющиеся понятие СРП, в прошлый раз было тока хранение данных.
G>>А это и есть. Ведь есть productId — данные, а ссылка product только слегка упрощает работу.
G>>Определение SRP одно, советую внимательно его изучить. Он является основопологающим принципом хоршего дизайна.
MC>), Поржал, вы тут с ИБ практикуете уникальное понимание СРП и при этом ты говориш мне его изучать .
http://en.wikipedia.org/wiki/Single_responsibility_principle
изучай.

G>>Это ты сам придумал. Денормализацию в твоем слуцчае это никак не оправдывает.

MC>Ты дорастеш до этого... Правда потерянные нолики могут оказаться критическими, ну да ладно. Ты же сам себе на уме.
Ну не отмазывайся. Там же вес, а не бабло.

G>>Можно пойти дальше, например есть у нас представление Order — Items, показанное выше и SalePeriod — Items, ты предложишь кешировать сумму по периоду тоже (учитывая доводы что ты приводил выше)? А где её кешировать?

MC>Смотря чего ты добиваешся. В закрытом периоде SalePeriod вполне можно и кешировать, в открытом оно не имеет смысл.
Все, не могу больше. Код в студию.
Давай с кешированием сумм по ордерам и закрытым периодам.
Банально CRUD для Itemов.

G>>А как после кучи таких кешировангий будет выглядеть код CUD для Item?

MC>Хз, у нас такого кода нет.
Что? позиции в заказы не добавляются?
Не верю (С) Станиславский.

G>>>>>>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?

MC>>>>>Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так.
G>>>>Какой процесс? Там же создание заказа? Почему "создание заказа" считает Total, а не кто либо еще, кому оно надо?
MC>>>Потому что тотал должен быть сохранен единожды быв посчитан. Никто другой не должен самочинствовать и его считать. Кто-то другой может посчтиать какой-то свой тотал.
G>>
G>>Ты расскажи зачем этот тотал нужен. Пока он никому не нужен его и считать не надо.
MC>При изменении непроданного ордера должен пересчитаться тотал.
Да не надо мне эту чушь говорить. Скажи кому этот тотал нужен.
Ты же там вес указал.

G>>А то получается что ты придумал фигню, а теперь придумываешь оправдания.

MC>Писец, что значит оправдания? Где оправдания? Это конкретная реаолизация с конкретными требованиями.
G>>Хочешь честно — давай исходные требования и разберем как их надо реализовывать.
MC>Выше. Я не представляю как ты будеш разбирать если у тебя нема представленя постороения таких систем...
Да ты полные требования (только не результат их интерпретации тобой) покажи.
Или хотябы замкнутое подмножество.

MC>>>>>Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?

G>>>>Потому что твой вариант таит больше проблем, чем ты можешь представить.
MC>>>Конкретней, плз.
G>>>>Нпапример пересчет тотала при добавлении\удалении\редактировании айтема.
MC>>>Ессно у нас то рич модел, у нас не может получиться что тотал будет посчитан не правильно. И да пересчет тотала происходит при операциях с айтемами.
G>>Уже начинаю плакать от смеха.
G>>Таким образом мы получили пеессимизацию на ровном месте.
G>>Кстати смотри выше SalePeriod — Items, как будешь выкручиваться?
MC>Выше.
Ну давай же код.

G>>>>Тебе понадобится поднять в память все айтемы для такой операции.

G>>>>Очень дорогостоящее редактирование атема выйдет, если учесть что отправка ордера может и не произойти.
MC>>>Мы подымаем в память весь ордер со всеми айтемами. У нас это не вызвает проблем.
G>>Браво, для редактирования одного айтема поднять в память полбазы — номальное явление для rich, ты это только что доказал.
MC>Да. Откуда ты взял пол базы? У нас есть понятие рут агрегата. Это обьект с четкими границами. У нас не бывает ситуаций когда неконтролированно подгружаеться что-то извне агрегата.
Это не отменяет того факта что для редактирования айтема надо поднимать много данных.

MC>И недозаполненый обьектов как у вас не бывает. У нас обьект всегда актуален.

И что вам это дает?

G>>>>Я кстати совершенно спокойно могу создать экстеншен метод AddItem и получить туже самую читаемоть что и у тебя.

MC>>>Добавив экстеншен метод у тебя получиться то о чем говорит ИБ.
G>>о чем он говорит?
MC>Что код говоно.
Доказательства?

MC>>>Ты не знаеш что делает AddItem.

G>>И ты не знаешь что делает AddItem в твоем случае. Это надо проверять тестами.
MC>Уже проверено. И гарантированно работает во всех инвариантах ордера. А твоя версия просто не может гарантировать инварианты.
Угу, у меня нету инвариантов ордера.
У меня тестами проверяется что нельзя сделать с ордером того, чего с ним делать нельзя.
У меня вообще ордер имеет состояние только потому что EF не поддерживает работу с Immutable данными.

MC>>>В рич моделе это решаеться скрытием состояния, рутагрегатами, боундариес, иммутабле валью обьектами и тому подобным.

G>>От кучи страшных слов гарантий не появится.
MC>Появляеться. Как бы ты не сопротивлялся.
Да никак не появляется. Кто тебе гарнтирует что под страшными словом не сидит баг?

MC>>>В анемик вы вообще никак не защищены от сайдеффектов.

G>>В rich вообще говоря тоже. Поэтому пишутся тесты.
MC>У нас запрещено выходить за приделы рут агрегатов, у нас запрещено выходить за приделы сервисов. На кажном уровне свои запреты. Причем для рут агрегатов это гарантируеться на компил тайме.
Каким образом?
ты запретишь кому-либо в compile time внутри рут агрегата создать SqlConnection?
Если да, то скажи как. Тоже юзать буду. А то пока по-старинке: тесты, да code review.

G>>Есдинственное отличие, что в anemic эти эффекты получить проще, но это проверяется тестами и программисты не заинектерованы писать неправильный код.

MC>Дава по пунктам.
MC>Как ты получиш сокрытие данных в анемик? Иммутабле? Ты не можеш их пользовать у тебя Linq2Sql.
Сначала скажи зачем мне скрывать данные? Обынчо наоборот — их показывать надо.

MC>Как ты получиш рутагрегатамы? Вспомни про разные вью.

Мне они не нужны. Я просто Linq запросы пишу и все. Рутагрегаты, это такой же костыль rich, как DTO.

MC>Как ты получиш боундариес? Тут проще в теории ничего сложного, но реально в рич моделях это на уровне практик, а в анемик про это даже не задумываються.

Да все тоже самое, только названий модных нету.

MC>>>AddItem у вас может полезть в какуюто левую проперти, полезть в БД и тому подобное. Вобщемто экстеншен метод это будет самы главный антиагрумент.

G>>Твой AddItem может сделать тоже самое. Тебе все равно нужен способ доказать что он этого не делает.
MC>Выше
G>>Кстати в случае экстеншена у него меньше возможностей полезть во внутренее состояние объекта, поэтому экстеншены предпочтительнее. В Design Guidelines так и написано.
MC>Ссылку. Ты забыл у тебя анемик у тебя все состояние наружу.
Это не касаемо anemic, это Framework Design Guidelines последней редакции.

MC>>>Ты еше можеш и партиал использовать.

G>>Партиал — обратный случай. Слишком много он может сделать с объектом.
MC>Что можно больше сделать с обьектом у которого все открыто?
Это тоже не касаемо anemic.
Re[14]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 15:36
Оценка: -1
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:



MC>>>И что? Это проблема?

G>>Вообще то да.
G>>Чтобы сформировать ProductListItem (три поля) тебе понадобится поднять в память весь product, весь список связанных Image, а только потом маппер сделает 3 поля.
MC>Если это станет проблемой, а оно не станет, как я говорил у нас кеши. Мы прикрутим кастомный репорт.
Уууу.... для такой простой операции еще и кеши... Ну вообще дец.
Все на надо больше доказывать что rich — говно. Я это и так знаю.

G>>Это просто нету сложных выборок. Например как получить список заказов с суммой , если сумма не кешируется в самом заказе?

MC>Незнаю, ты придумал себе проблему ты и решай. У нас суммы не кешируються. У нас они сохраняються.
А небо не голубое, а светлосинее?
Я такую проблему спокойно решаю, по несколько раз в день. Просто пишу Linq запрос.
А вот как ты эту проблему решишь с таким подходом даже интересно.
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Sergey T. Украина http://overstore.codeplex.com
Дата: 29.05.09 15:39
Оценка:
Здравствуйте, gandjustas, Вы писали:


ЛИ>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.

G>
G>Я бы архитектора выгнал сразу за такие слова.
G>Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб.

Подозреваю, что буду десятым человеком, прицепившимся к этой фразе, но во-первых: к объектам на разных слоях могут применяться разные требования, и разработка универсального дизайнерского решения для покрытия двух наборов требований может вылиться в конце-концов в датасеты, и увеличение издержек. Во-вторых, какой именно код не должен меняться? Код представления, очевидно, не то что поменяется — перепишется заново. Код модели — поменяется вряд-ли, если только он не был разработан с оглядкой на UI.

ЛИ>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

G>Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся.
Проблему составляет не отложенная загрузка как таковая (хотя если используется проксирование, то прокси нужно научить правильно сериализировать себя), а большая иерархичность модели.

ЛИ>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

G>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем.
G>Покажите пример кода, где по rich гораздо удобнее anemic.
Сорри, что отвечаю не вам, а человеку, которому отвечали вы. Как раз большие объемы данных — это хороший повод использовать объекты, потому как в .NET-е, по крайней мере, надо пользоваться или датаридером, или, если это невозможно, то восстанавливать объекты. Потому что если задача требует хранить данные в памяти (подчеркиваю жирным и красным ), то объекты и массивы — это наиболее удобный, экономный и естественный способ представления данных. Любые контейнеры данных будут заведомо более избыточны, чем объекты. Конечно, возможна экзотика, когда такой подход неприменим: например, резалтсеты разной структуры. И конечно же, само собой, то, что можно делать в базе, надо делать в базе.
There is no such thing as the perfect design.
Re[16]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 15:39
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Здравствуйте, gandjustas, Вы писали:


G>>Юзкейс из моего проекта. Только админ может видеть\редактировать\еще_что_то_делать с сущностями X, которые невидимы (Visible = false).

G>>Короче для каждой операции надо накладывать условие выборки. У меня всо всех случаях (хоть репортиг, хоть что-то еще) делает это один и тот же код.
G>>(На самом деле это делается для всех сущностей, у которых есть видимость, одним и тем же кодом)

G>>В твоем случае придется два раза писать для reporting и domain.


MC>Я не вижу дублирования.


MC>1) Первое у нас в продукте есть Multitenancy. Это когда в одной БД можут находиться несколько разных приложений (это мы економим на хосете моде). Реализвано приблизительно как в http://java.dzone.com/articles/introduction-hibernate-filters У нас аналогичное тока програмно. Мы не используем ХМЛ.

MC>Фактически с фильтром приложение не видит ничего из того что ей не позволено.

MC>2) Ну а второе, секурити тримминг это не респонсибилити модели. Этим может заниматься тока ендинтерфейс, ну или аппликейшен фасады. В домене вообще нема понятия Админа.


Ну и как такое требование реализуется поверх domain model во всех кейсах?
Неважно что там будет между UI и моделью.
Кстати это по твоей классификации логикой является?
Re[4]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 15:53
Оценка:
Здравствуйте, Sergey T., Вы писали:

ST>Здравствуйте, gandjustas, Вы писали:



ЛИ>>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае.

G>>
G>>Я бы архитектора выгнал сразу за такие слова.
G>>Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб.

ST>Подозреваю, что буду десятым человеком, прицепившимся к этой фразе, но во-первых: к объектам на разных слоях могут применяться разные требования, и разработка универсального дизайнерского решения для покрытия двух наборов требований может вылиться в конце-концов в датасеты, и увеличение издержек.

Не надо проектировать в терминах объектов. Проектировать надо в терминах функций.

ST>Во-вторых, какой именно код не должен меняться? Код представления, очевидно, не то что поменяется — перепишется заново. Код модели — поменяется вряд-ли, если только он не был разработан с оглядкой на UI.

Да, такова теория. Она разбивается о жестокую реальность stateless веба и запросоориентированности.
Надо быть по-настоящему крутым архитектором чтобы обеспечить возможность такого перехода безболезненно.

ЛИ>>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

G>>Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся.
ST>Проблему составляет не отложенная загрузка как таковая (хотя если используется проксирование, то прокси нужно научить правильно сериализировать себя), а большая иерархичность модели.
Мне иерархичность модели никогда не мешала (в SQL то она не мешает). Мешают именно средства работы с этой иерархией.
Re[5]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 29.05.09 21:09
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Не надо проектировать в терминах объектов. Проектировать надо в терминах функций.

Ничего себе заявочки )

G>Да, такова теория. Она разбивается о жестокую реальность stateless веба и запросоориентированности.

G>Надо быть по-настоящему крутым архитектором чтобы обеспечить возможность такого перехода безболезненно.
А пафоса-то ) Имхо REST вообще отлично туда укладывается. Странно, тоже теория

G>Мне иерархичность модели никогда не мешала (в SQL то она не мешает). Мешают именно средства работы с этой иерархией.

Т.е. работать без средств проще, чем с ними. Превосходно.

Уважаемый gandjustas, беседовать с вами очень интересно; у вас что ни фраза, то парадокс ) надеюсь, вам это не мешает
Re[6]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.05.09 21:27
Оценка:
Здравствуйте, meowth, Вы писали:

G>>Да, такова теория. Она разбивается о жестокую реальность stateless веба и запросоориентированности.

G>>Надо быть по-настоящему крутым архитектором чтобы обеспечить возможность такого перехода безболезненно.
M>А пафоса-то ) Имхо REST вообще отлично туда укладывается. Странно, тоже теория
Причем тут REST?
Я участвовал один раз в процессе переделки десктопного приложения в веб.
Тоже сначала говорили что только PL поменяется и все. А на деле 90% понадобилось переписать.
И если поизучать опыт других, то таких случаев окажется очень много.

G>>Мне иерархичность модели никогда не мешала (в SQL то она не мешает). Мешают именно средства работы с этой иерархией.

M>Т.е. работать без средств проще, чем с ними. Превосходно.
Не выдумывай. Я не написал что мешают все средства, мешают только некоторые, такие как LL например.
Re[15]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 30.05.09 15:34
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>По-твоему, для domain этот код плох, потому что он с слишком DTO-ориентирован, для репортинга плох, потому что не такой же, как для domain, хотя и лезет в domain, а для presentation layer я так и не понял почему плох, но у тебя он вызвал сильное отторжение.

G>Это ты что-то придумал.
Ничего не придумал, вы сами сказали следующее: "G>>>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting."

G>Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.

Весь не надо, есть проекции и срезы. Кроме того, инфраструктура обеспечивает совершенно прозрачный для бизнес-скрипта кэш объектов.

G>Кроме того, если нужны запросы с аггрегатными операциями, что придумаете?

Придумывать ничего не надо, надо написать запрос с аггрегатными операциями.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 30.05.09 15:38
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Да, такова теория. Она разбивается о жестокую реальность stateless веба и запросоориентированности.

G>>>Надо быть по-настоящему крутым архитектором чтобы обеспечить возможность такого перехода безболезненно.
M>>А пафоса-то ) Имхо REST вообще отлично туда укладывается. Странно, тоже теория :
G>Причем тут REST?
При том, что это теория, но о "жестокую реальность" не разбивается, вполне мирно сосуществует.

G>Я участвовал один раз в процессе переделки десктопного приложения в веб.

G>Тоже сначала говорили что только PL поменяется и все. А на деле 90% понадобилось переписать.
G>И если поизучать опыт других, то таких случаев окажется очень много.
Здесь спорить не буду, ибо может у вас все по-другому. Мне ни разу не встречалось, ничего не могу сказать. Имхо anemic только для этого и хорош -- если вдруг ВНЕЗАПНО надо идти в web, а DTO писать "ломает". Кстати я смотрю, "только один раз".

G>>>Мне иерархичность модели никогда не мешала (в SQL то она не мешает). Мешают именно средства работы с этой иерархией.

M>>Т.е. работать без средств проще, чем с ними. Превосходно.
G>Не выдумывай. Я не написал что мешают все средства, мешают только некоторые, такие как LL например.
В другом посте вы сказали, что для anemic тоже есть инфраструктура, обеспечивающая persistence ignorance. LL -- это ее важная часть. А тут вдруг оказывается, что LL -- мешает. Интересная у вас логика. Об ее "жестокуюю реальность" "разбивается" моя точка зрения )
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 30.05.09 22:32
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>>>Да, такова теория. Она разбивается о жестокую реальность stateless веба и запросоориентированности.

G>>>>Надо быть по-настоящему крутым архитектором чтобы обеспечить возможность такого перехода безболезненно.
M>>>А пафоса-то ) Имхо REST вообще отлично туда укладывается. Странно, тоже теория :
G>>Причем тут REST?
M>При том, что это теория, но о "жестокую реальность" не разбивается, вполне мирно сосуществует.

Теория заключается в том что в обычном двузвенном десктоп приложении при переделке в веб придется переписать только PL.
Практика заключается в том что таких случаев до смешного мало, переписывать приходится до 90%.

G>>Я участвовал один раз в процессе переделки десктопного приложения в веб.

G>>Тоже сначала говорили что только PL поменяется и все. А на деле 90% понадобилось переписать.
G>>И если поизучать опыт других, то таких случаев окажется очень много.
M>Здесь спорить не буду, ибо может у вас все по-другому. Мне ни разу не встречалось, ничего не могу сказать. Имхо anemic только для этого и хорош -- если вдруг ВНЕЗАПНО надо идти в web, а DTO писать "ломает". Кстати я смотрю, "только один раз".
Все неожиданные требования появляются внезапно.

G>>>>Мне иерархичность модели никогда не мешала (в SQL то она не мешает). Мешают именно средства работы с этой иерархией.

M>>>Т.е. работать без средств проще, чем с ними. Превосходно.
G>>Не выдумывай. Я не написал что мешают все средства, мешают только некоторые, такие как LL например.
M>В другом посте вы сказали, что для anemic тоже есть инфраструктура, обеспечивающая persistence ignorance.
не надо выдумывать. я говорил что в anemic используются теже средства persistance, что и для rich. Какую функциональность этих средств использовать — отдельный вопрос.
Re: Anemic Domain Model vs Rich Domain Model
От: Воронков Василий Россия  
Дата: 31.05.09 00:03
Оценка:
Здравствуйте, GlebZ, Вы писали:

Мне вот непонятно, почему рассуждая о Rich модели и о Фаулере, всегда забывают о ряде моментов.
Во-первых, бизнес-логика, связанная с, скажем, организацией, необязательно должна быть защита в класс Организация — если эта логика внешняя по отношению к организации, например набор бизнес-правил, оно может (и должна быть) представлена в виде отдельных бизнес-сущностей. Во-вторых помимо собственно domain, у Фаулера есть еще такая штука как infrastructure.

А все отличия сводятся к:

Employer[] OrganizationService.GetEmployers(Organization org){…}
Employer[] Organization.GetEmployers(){…}

Хотя это вообще шутка сугубо декоративная. Я напишу себе экстеншин методы и у меня вариант 1 превратится в вариант 2. Это какая модель тогда будет? А если организацию при создании параметризировать сервисом, вызов в который она будет делегировать для получения списка емплоееров?
Re[14]: Anemic Domain Model vs Rich Domain Model
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 31.05.09 04:48
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Если это станет проблемой, а оно не станет, как я говорил у нас кеши. Мы прикрутим кастомный репорт.


Ага, а потом поставим приложение на веб-ферму или кластер и — упс — накрылись медным тазом наши кэши... Лично я больше всего ненавижу рич модель именно за эти кэши, которые при развитии проекта всегда путаются под ногами...
[КУ] оккупировала армия.
Re[16]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 05:53
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>>>По-твоему, для domain этот код плох, потому что он с слишком DTO-ориентирован, для репортинга плох, потому что не такой же, как для domain, хотя и лезет в domain, а для presentation layer я так и не понял почему плох, но у тебя он вызвал сильное отторжение.

G>>Это ты что-то придумал.
M>Ничего не придумал, вы сами сказали следующее: "G>>>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting."
Я констатировал факт.

G>>Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.

M>Весь не надо, есть проекции и срезы. Кроме того, инфраструктура обеспечивает совершенно прозрачный для бизнес-скрипта кэш объектов.
Да ну? И как делать проекции и срезы с domain model? А в кеш не полностью объекты тянутся?

G>>Кроме того, если нужны запросы с аггрегатными операциями, что придумаете?

M>Придумывать ничего не надо, надо написать запрос с аггрегатными операциями.
Ну а как же domain model? Что там поймет domain expert?
Или снова получается что самая rich модель является таковой процентов на 5-10?
Re[2]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 05:58
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Здравствуйте, GlebZ, Вы писали:


ВВ>Во-первых, бизнес-логика, связанная с, скажем, организацией, необязательно должна быть защита в класс Организация — если эта логика внешняя по отношению к организации, например набор бизнес-правил, оно может (и должна быть) представлена в виде отдельных бизнес-сущностей.

И как такой класс назвываться будет? Думаете в предметной области будет такое понятие, как вы придумаете для этого класса?

ВВ>Во-вторых помимо собственно domain, у Фаулера есть еще такая штука как infrastructure.

Это то что не бизнес-логика.

ВВ>А все отличия сводятся к:

ВВ>Employer[] OrganizationService.GetEmployers(Organization org){…}
ВВ>Employer[] Organization.GetEmployers(){…}
Это только в самом простом случае.


ВВ>Хотя это вообще шутка сугубо декоративная. Я напишу себе экстеншин методы и у меня вариант 1 превратится в вариант 2. Это какая модель тогда будет?

Все равно anemic.

ВВ>А если организацию при создании параметризировать сервисом, вызов в который она будет делегировать для получения списка емплоееров?

Это будет уже идиотизм. Так как сущности окажутся привязаны к сервисам без необходимости. А в остальном код такой же как в anemic будет.
Re[17]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 06:27
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>Ничего не придумал, вы сами сказали следующее: "G>>>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting."

G>Я констатировал факт.
Ну а я его опроверг

G>>>Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.

M>>Весь не надо, есть проекции и срезы. Кроме того, инфраструктура обеспечивает совершенно прозрачный для бизнес-скрипта кэш объектов.
G>Да ну? И как делать проекции и срезы с domain model? А в кеш не полностью объекты тянутся?
Очень просто. Читайте NHibernate API и справочник по HQL. Читайте там, я уже писал, что в кеше лежат "т.н. deghydrated objects", разобранные на данные. Тянутся так, как вы напишете.

G>Ну а как же domain model? Что там поймет domain expert?

G>Или снова получается что самая rich модель является таковой процентов на 5-10?
Не заметил противоречий. В HQL аггрегаты поддерживаются наравне с domain query, для domain expert никакой разницы не наблюдается.
Пример:
"from SomeItems as si select si, count(si.children)".List();
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 31.05.09 06:35
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>Хотел бы подвергнуть сомнению все эти пункты:

ЛИ>>1) Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM;
GZ>Тут я бы проитерполировал сложность сопровождения в зависимости от количества сущностей. При большом количестве, RDM должен быть эффективней. Но RDM также приводит к более высоким требованиям по качеству архитектуры и качеству дизайна.

Это безусловно. Одно из преимуществ ADM -- простота дизайна в смысле нетребовательности к квалификации разработчиков и проектировщиков.

ЛИ>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае. Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет;

GZ>В паттернах Фаулера есть ключевое слово Enterprise о котором часто забывают. А это практически всегда означает, что клиенты как минимум хотят с кем-то, зачем-то интегрироваться. Поэтому переносимость нужна. А ежели объекты отчуждаемы, то это ващщее...

Полностью согласен на счёт неизбежности задачи интеграции в корпоративных информационных системах, но она чрезвычайно редко делается с помощью простой сериализации -- опасно завязывать контракт на внутренней структуре классов. Поэтому даже в простейшем случае так или иначе используется data binding, для которого не существенна разница между RDM и ADM.

GZ>Кроме того, даже на уровне потребления нельзя использовать голые классы. Иначе мы нарушаем изоляцию через фасад.


Честно говоря, не понял, что имеется в виду.

ЛИ>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM;

GZ>В том то и дело, что ADM все это нормально переваривает без костылей.

ЛИ>>4) Постоянная валидность бизнес-объектов и RDM -- совершенно не связанные между собой аспекты, в случае ADM точно так же можно наложить ограничение постоянной валидности.

GZ>В ADM это как раз сделать очень сложно.

ЛИ>>К тому же современные средства валидации бизнес-объектов поддерживают несколько степеней валидности, в зависимости от контекста.

GZ>Без возражений. Только вопрос что имелось ввиду под средствами?

Про .Net не скажу, но в JEE есть несколько библиотек и целый стандарт JSR 303: Bean Validation, который описывает как с помощью аннотаций декларативно описывать присущие объекту инварианты, а так же как их валидировать.

ЛИ>>То, что Вы называете сглаживанием недостатков модели, я бы назвал просто правильным способом реализации RDM

GZ>Немножко добавлю. Я — разработчик NET. В случае реализации ADM, я собираю приложения не пользуясь излишним инструментарием(ну ессно это не касается отчетов, OLAP и другой специализации). Это позволяет уменьшать сложность вхождения в проект, углубляет понимание самих процессов происходящих в решении. Я могу на коленке, собрать приложение любой степени сложности. И второе, что хотелось бы повторить. Я хочу не отвлекаться на правильность дизайна OOP. В реальности, реализация правильного дизайна OOP — весьма сложная штукенция. Можно заделать грабли.

Одно из соображений, которое я приводил у себя в блоге, это то, что без использования хорошего инструментария ORM лучше даже и не связываться с RDM, потому что выйдет сложно. В этом смысле ORM -- тот самый случай enabling technology, открывающей возможности. А вот насколько это "правильно", мне кажется, дело вкуса и личных пристрастий.

ЛИ>>P.S. Совсем недавно я писал развёрнутую статью на эту тему у себя в блоге, если любопытно:

ЛИ>>http://javatoday.ru/2009/03/rich-domain-model/
GZ>Что-то уж очень страшное. Или я ваще ничего не понял, или одно из двух. У постановки может быть большое кол-во графов. Ну например, есть иерархия подчинения, типа отдел с директором, подчиненные подразделения и т.д. А есть проектные группы, которым эта иерархия ваще по барабану, так как там 3 чела с одного подразделения, 2 чела с другого. И у этих двух иерархий, независимые связи и некоторая ортогональная логика. Зачем мешать все в одном объекте? Не проще ли выделить некоторую логику в раздельные сервисы? Band of Four здря книжки писали?

Вы привели очень хороший пример, давайте только его разрисуем. Вот сущности:
1) Отдел
1.1) Ассоциация "директор" -> Работник[1]
1.2) Ассоциация "сотрудники" -> Работник[0..*]
2) Проект
2.1) Ассоциация "руководитель" -> Работник[1]
2.2) Ассоциация "участники" -> Работник[1..*]
3) Работник
3.1) Ассоциация "отдел в подчинении" (обратная сторона "Отдел.директор") -> Отдел[0..1]
3.2) Ассоциация "сотрудник отдела" (обратная сторона "Отдел.сотрудники") -> Отдел[1]
3.3) Ассоциация "проекты в управлении" (обратная сторона "Проект.руководитель") -> Проект[0..*]
3.4) Ассоциация "участвует в проектах" (обратная сторона "Проект.участники") -> Проект[0..*]

По сути, Ваш вопрос можно переформулировать: стоит ли мешать в один класс Работник все 4 ассоциации или следует разделить класс на две несвязанные половинки: "Сотрудник отдела" и "Участник проекта". Делить не стоит, потому что не смотря на полную независимость иерархий, в каких-то сценариях потребуется навигация одновременно по двум иерархиям. В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.
Re[15]: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 31.05.09 06:37
Оценка: 1 (1)
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Если это станет проблемой, а оно не станет, как я говорил у нас кеши. Мы прикрутим кастомный репорт.


K>Ага, а потом поставим приложение на веб-ферму или кластер и — упс — накрылись медным тазом наши кэши... Лично я больше всего ненавижу рич модель именно за эти кэши, которые при развитии проекта всегда путаются под ногами...


А Вы используйте правильные кэши, которые дружат с кластером.
Re[15]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 07:35
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, Mike Chaliy, Вы писали:


MC>>Если это станет проблемой, а оно не станет, как я говорил у нас кеши. Мы прикрутим кастомный репорт.


K>Ага, а потом поставим приложение на веб-ферму или кластер и — упс — накрылись медным тазом наши кэши... Лично я больше всего ненавижу рич модель именно за эти кэши, которые при развитии проекта всегда путаются под ногами...


Ой, какие нехорошие кеши, путаются все время
У меня кластер из серверов приложений, ничего не путаются. Наверное, потому, что shared cache, как делают все разработчики, использующие фермы.
Re[9]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 07:40
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Теория заключается в том что в обычном двузвенном десктоп приложении при переделке в веб придется переписать только PL.

G>Практика заключается в том что таких случаев до смешного мало, переписывать приходится до 90%.
В таком случае что anemic, что rich -- разницы с точки зрения трудоемкости развития нету.

G>Все неожиданные требования появляются внезапно.

Не хочу спорить на эту тему. Скажу только, что у нас в проекте в документе vision практикуется раздел system evolution, где описаны evolution plans и extension points проекта; и проектирование ведется с учетом этих рисков. Это спасает от "внезапных" требований.
Re[3]: Anemic Domain Model vs Rich Domain Model
От: Воронков Василий Россия  
Дата: 31.05.09 08:14
Оценка:
Здравствуйте, gandjustas, Вы писали:

ВВ>>Во-первых, бизнес-логика, связанная с, скажем, организацией, необязательно должна быть защита в класс Организация — если эта логика внешняя по отношению к организации, например набор бизнес-правил, оно может (и должна быть) представлена в виде отдельных бизнес-сущностей.

G>И как такой класс назвываться будет? Думаете в предметной области будет такое понятие, как вы придумаете для этого класса?

Мне разжевать и в рот положить? Я сказал, что если логика внешняя по отношению к Организации, она не должна содержаться в классе Организация. Если эта логика внешняя, то очевидно "в предметной области" и понятие такое найдется.

ВВ>>А если организацию при создании параметризировать сервисом, вызов в который она будет делегировать для получения списка емплоееров?

G>Это будет уже идиотизм. Так как сущности окажутся привязаны к сервисам без необходимости. А в остальном код такой же как в anemic будет.

Вот когда придет понимание, что привязка сущностей к сервисам куда лучше лучше чем зависимость сервисов от контрактов сущностей — что противоречит даже большинству сервис-ориентед паттернов — тогда и станет понятно, чем хороша жирная модель.
Re[16]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 31.05.09 10:40
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, koandrew, Вы писали:


K>>Здравствуйте, Mike Chaliy, Вы писали:


MC>>>Если это станет проблемой, а оно не станет, как я говорил у нас кеши. Мы прикрутим кастомный репорт.


K>>Ага, а потом поставим приложение на веб-ферму или кластер и — упс — накрылись медным тазом наши кэши... Лично я больше всего ненавижу рич модель именно за эти кэши, которые при развитии проекта всегда путаются под ногами...


M>Ой, какие нехорошие кеши, путаются все время

M>У меня кластер из серверов приложений, ничего не путаются. Наверное, потому, что shared cache, как делают все разработчики, использующие фермы.

+1. У нас УЖЕ лоад-белансед ферма.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[17]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 12:15
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>+1. У нас УЖЕ лоад-белансед ферма.


Если не NDA, вы как сделали, на основе штатного NLB? А то я уже в сторону 1 nginx + N IIS поглядываю, изучаю вопрос.
Re[18]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 31.05.09 12:33
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, Mike Chaliy, Вы писали:


MC>>+1. У нас УЖЕ лоад-белансед ферма.


M>Если не NDA, вы как сделали, на основе штатного NLB? А то я уже в сторону 1 nginx + N IIS поглядываю, изучаю вопрос.


Я если чесно не в курсе . Насколько я знаю да, штатный NLB из 2008 винды.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[18]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 13:19
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>>>Ничего не придумал, вы сами сказали следующее: "G>>>Ага, теперь нам надо разный код писать для работы с товарами категории X в domain и в reporting."

G>>Я констатировал факт.
M>Ну а я его опроверг
Чем? Тем что придумали что не будет шарится логика между reporting и domain?
Я привел пример как в anemic шарится логика между такими аспектами (хотя на самом деле там нет разницы), что вы будете опреовергать?

G>>>>Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.

M>>>Весь не надо, есть проекции и срезы. Кроме того, инфраструктура обеспечивает совершенно прозрачный для бизнес-скрипта кэш объектов.
G>>Да ну? И как делать проекции и срезы с domain model? А в кеш не полностью объекты тянутся?
M>Очень просто. Читайте NHibernate API и справочник по HQL. Читайте там, я уже писал, что в кеше лежат "т.н. deghydrated objects", разобранные на данные. Тянутся так, как вы напишете.
И как тогда domain-объекты с неполными данными работают?
То что технически такая возможность есть я не сомневаюсь.

G>>Ну а как же domain model? Что там поймет domain expert?

G>>Или снова получается что самая rich модель является таковой процентов на 5-10?
M>Не заметил противоречий. В HQL аггрегаты поддерживаются наравне с domain query, для domain expert никакой разницы не наблюдается.
M>Пример:
M>"from SomeItems as si select si, count(si.children)".List();
И какого типа объекты получатся? Это будут domain objects? Как потом логику применять к результатам такого запроса?
Re[4]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 13:27
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.


Очень наивно так полагать.
Я один раз исправлял один тормзящий код. Тормоза были именно из-за LL. Когда посмотрел профайлером оказалось что на простую на вид операцию к базе шло около сотни запросов.
Посмотрел внутренности, оказалось что в безобидном на вид методе (типа AddItem) было обращение к дочерней коллекции, которая подтягивалась лениво.
А так как был зайдействован Linq2SQL, то он тянул всю коллекцию связнынх объектов на каждое обращение. И метод этот вызывался в цикле.
Отключение LL и загрузка только нужных данных дала офигенный прирост производительности. Для этого понадобилость только 3 строчки написать.
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 13:29
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>Теория заключается в том что в обычном двузвенном десктоп приложении при переделке в веб придется переписать только PL.

G>>Практика заключается в том что таких случаев до смешного мало, переписывать приходится до 90%.
M>В таком случае что anemic, что rich -- разницы с точки зрения трудоемкости развития нету.
Это вообще другая ветка разговора.
Re[4]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 13:41
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Здравствуйте, gandjustas, Вы писали:


ВВ>>>Во-первых, бизнес-логика, связанная с, скажем, организацией, необязательно должна быть защита в класс Организация — если эта логика внешняя по отношению к организации, например набор бизнес-правил, оно может (и должна быть) представлена в виде отдельных бизнес-сущностей.

G>>И как такой класс назвываться будет? Думаете в предметной области будет такое понятие, как вы придумаете для этого класса?

ВВ>Мне разжевать и в рот положить? Я сказал, что если логика внешняя по отношению к Организации, она не должна содержаться в классе Организация. Если эта логика внешняя, то очевидно "в предметной области" и понятие такое найдется.

Ну это получится сервис в терминах anemic — класс содержащий логику обработки данных, и не содержащий самих данных.
А если детально проанализировать предметную область, то окажется что очень мало объектов на самом деле обладают поведением.

ВВ>>>А если организацию при создании параметризировать сервисом, вызов в который она будет делегировать для получения списка емплоееров?

G>>Это будет уже идиотизм. Так как сущности окажутся привязаны к сервисам без необходимости. А в остальном код такой же как в anemic будет.

ВВ>Вот когда придет понимание, что привязка сущностей к сервисам куда лучше лучше чем зависимость сервисов от контрактов сущностей — что противоречит даже большинству сервис-ориентед паттернов — тогда и станет понятно, чем хороша жирная модель.


Давай в коде.
ты предлагаешшь:

class SomeService: ISomeService
{
   public void SomeAction(SomeDomainObject o)
   {
      //blah-blah-blah
   }
}

class SomeDomainObject
{
  public SomeDomainObject(ISomeSerivice srv)
  {
    _service = srv;
  }

  public void SomeAction()
  {
    _service.SomeAction(this);
  }

  //Some data
}

//где-то в коде
SomeDomainObject o = _someRepo.getObjectWithInjectedSerice(new SomeService(), ...);
o.SomeAction();


Я предлагаю

class SomeService: ISomeService
{
   public void SomeAction(SomeDomainObject o)
   {
      //blah-blah-blah
   }
}

class SomeDataObject
{ 
  //Some data
}

//где-то в коде
SomeDataObject o = _someRepo.Get(...);
var srv = new SomeService();
svr.SomeAction(o);


В моем связность меньше. При этом еще код repository проще будет.

Что не так?
Re[19]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 13:52
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Чем? Тем что придумали что не будет шарится логика между reporting и domain?

G>Я привел пример как в anemic шарится логика между такими аспектами (хотя на самом деле там нет разницы), что вы будете опреовергать?
Мне показалось, вы привели пример, что в rich эта логика шарится НЕ будет. Его я и опроверг.

G>>>>>Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.

M>>>>Весь не надо, есть проекции и срезы. Кроме того, инфраструктура обеспечивает совершенно прозрачный для бизнес-скрипта кэш объектов.
G>>>Да ну? И как делать проекции и срезы с domain model? А в кеш не полностью объекты тянутся?
M>>Очень просто. Читайте NHibernate API и справочник по HQL. Читайте там, я уже писал, что в кеше лежат "т.н. deghydrated objects", разобранные на данные. Тянутся так, как вы напишете.
G>И как тогда domain-объекты с неполными данными работают?
G>То что технически такая возможность есть я не сомневаюсь.
Во-первых, очень хорошо, что вы не спорите, что есть такая техническая возможность
Во-вторых, вы что-путаете. Что значит -- "с неполными данными"? В anemic как-то по-другому данные в коде оказываются, без запроса к БД?

G>>>Ну а как же domain model? Что там поймет domain expert?

G>>>Или снова получается что самая rich модель является таковой процентов на 5-10?
M>>Не заметил противоречий. В HQL аггрегаты поддерживаются наравне с domain query, для domain expert никакой разницы не наблюдается.
M>>Пример:
M>>"from SomeItems as si select si, count(si.children)".List();
G>И какого типа объекты получатся? Это будут domain objects? Как потом логику применять к результатам такого запроса?
Того типа, в который вы сконвертите. Ну если вы просили аггрегаты показать, значит, есть такой domain объект, в котором представим аггрегат. Логику применять -- как обычно.
Re[5]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 14:00
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.


G>Очень наивно так полагать.

G>Я один раз исправлял один тормзящий код. Тормоза были именно из-за LL. Когда посмотрел профайлером оказалось что на простую на вид операцию к базе шло около сотни запросов.
G>Посмотрел внутренности, оказалось что в безобидном на вид методе (типа AddItem) было обращение к дочерней коллекции, которая подтягивалась лениво.
G>А так как был зайдействован Linq2SQL, то он тянул всю коллекцию связнынх объектов на каждое обращение. И метод этот вызывался в цикле.
G>Отключение LL и загрузка только нужных данных дала офигенный прирост производительности. Для этого понадобилость только 3 строчки написать.

Имхо вы тут путаетесь. Как LL может повлиять на то, что в цикле будут вытягиваться лишние данные? Как он может повлиять на то, что по каждому обращению данные будут вытягиваться заново из БД (объектный 2хуровневый кеш таки рулит(?
ИМХО то, что linq2sql не дает настроить batch size loading в LL еще не значит, что LL -- это плохо и тормозно.
Re[16]: Anemic Domain Model vs Rich Domain Model
От: koandrew Канада http://thingselectronic.blogspot.ca/
Дата: 31.05.09 14:01
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>А Вы используйте правильные кэши, которые дружат с кластером.


И где эти кэши будут физически находиться? На одной из нод кластера — слабая надёжность, на отдельной ноде — тоже слабо... Так где?
[КУ] оккупировала армия.
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 31.05.09 14:09
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.


G>Очень наивно так полагать.


Я всё же предлагаю разделять случаи, когда "должно, но не работает" и "в принципе не должно". Первое лечится багфиксингом, второе -- нет.
Re[17]: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 31.05.09 14:20
Оценка:
Здравствуйте, koandrew, Вы писали:

K>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>А Вы используйте правильные кэши, которые дружат с кластером.


K>И где эти кэши будут физически находиться? На одной из нод кластера — слабая надёжность, на отдельной ноде — тоже слабо... Так где?


Есть разные варианты:
1) Самый простой: кэш локален на каждом узле, согласованность обеспечивается синхронной инвалидацией;
2) Для кэша используются отдельные специализированные узлы. Это стандартное решение для создания высоконагруженных приложений на платформе LAMP+memcached;
3) Самый сложный: данные в кэше автоматически реплицируются и балансируются между узлами, что обеспечивает высокую надёжность. Ключевые слова: consistent hashing, in-memory data grid, cache partitioning. Сейчас (по крайней мере в JEE) такое умеют только дорогие проприетарные продукты типа Oracle Coherence, но на подходе и open source альтернативы.
Re[20]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 14:24
Оценка:
Здравствуйте, meowth, Вы писали:

G>>>>>>Только для этого надо поднять в память сначала весь объект. А это может быть непозволительно долго.

M>>>>>Весь не надо, есть проекции и срезы. Кроме того, инфраструктура обеспечивает совершенно прозрачный для бизнес-скрипта кэш объектов.
G>>>>Да ну? И как делать проекции и срезы с domain model? А в кеш не полностью объекты тянутся?
M>>>Очень просто. Читайте NHibernate API и справочник по HQL. Читайте там, я уже писал, что в кеше лежат "т.н. deghydrated objects", разобранные на данные. Тянутся так, как вы напишете.
G>>И как тогда domain-объекты с неполными данными работают?
G>>То что технически такая возможность есть я не сомневаюсь.
M>Во-первых, очень хорошо, что вы не спорите, что есть такая техническая возможность
M>Во-вторых, вы что-путаете. Что значит -- "с неполными данными"? В anemic как-то по-другому данные в коде оказываются, без запроса к БД?
Я про другое спрашивал. На что мапится результат выборки? На какие domain objects? Как потом эти данные обрабатываются?

G>>>>Ну а как же domain model? Что там поймет domain expert?

G>>>>Или снова получается что самая rich модель является таковой процентов на 5-10?
M>>>Не заметил противоречий. В HQL аггрегаты поддерживаются наравне с domain query, для domain expert никакой разницы не наблюдается.
M>>>Пример:
M>>>"from SomeItems as si select si, count(si.children)".List();
G>>И какого типа объекты получатся? Это будут domain objects? Как потом логику применять к результатам такого запроса?
M>Того типа, в который вы сконвертите. Ну если вы просили аггрегаты показать, значит, есть такой domain объект, в котором представим аггрегат. Логику применять -- как обычно.
А если нет? Например есть заказ. У него есть позиции. В одном случае надо получить заказ с суммой, в другом сумма нафиг не нужна, а в третьем вовсе надо сгруппировать по месяцам и суммы получить.
А в предметной области есть только "заказ" и все.
Re[6]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 14:27
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>>В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.


G>>Очень наивно так полагать.

G>>Я один раз исправлял один тормзящий код. Тормоза были именно из-за LL. Когда посмотрел профайлером оказалось что на простую на вид операцию к базе шло около сотни запросов.
G>>Посмотрел внутренности, оказалось что в безобидном на вид методе (типа AddItem) было обращение к дочерней коллекции, которая подтягивалась лениво.
G>>А так как был зайдействован Linq2SQL, то он тянул всю коллекцию связнынх объектов на каждое обращение. И метод этот вызывался в цикле.
G>>Отключение LL и загрузка только нужных данных дала офигенный прирост производительности. Для этого понадобилость только 3 строчки написать.

M>Имхо вы тут путаетесь. Как LL может повлиять на то, что в цикле будут вытягиваться лишние данные? Как он может повлиять на то, что по каждому обращению данные будут вытягиваться заново из БД (объектный 2хуровневый кеш таки рулит(?

M>ИМХО то, что linq2sql не дает настроить batch size loading в LL еще не значит, что LL -- это плохо и тормозно.

Еще раз если не заметили: проблема была исправлена тремя строчками с указанием явной загрузки нужных данных. Без двухуровневых объектных кешей и прочей лабуды.
Кстати как кеш обеспечивает когерентность в условиях работы нескольких приложений с одной базой (без общего кеша)? или просто при использовании ХП?
Re[6]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 14:28
Оценка:
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>>В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.


G>>Очень наивно так полагать.


ЛИ>Я всё же предлагаю разделять случаи, когда "должно, но не работает" и "в принципе не должно". Первое лечится багфиксингом, второе -- нет.


LL создает условия возникновения таких ошибок.
Re[21]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 14:43
Оценка: :)
Здравствуйте, gandjustas, Вы писали:

M>>Во-вторых, вы что-путаете. Что значит -- "с неполными данными"? В anemic как-то по-другому данные в коде оказываются, без запроса к БД?

G>Я про другое спрашивал. На что мапится результат выборки? На какие domain objects? Как потом эти данные обрабатываются?
Хм, надеюсь, я понял вас правильно. Результат выборки мапится на объект, которому потребовался срез. Чаще всего это UI DTO или Reporting DTO, или просто plain data (в этом случае никуда не мапится).

M>>Того типа, в который вы сконвертите. Ну если вы просили аггрегаты показать, значит, есть такой domain объект, в котором представим аггрегат. Логику применять -- как обычно.

G>А если нет? Например есть заказ. У него есть позиции. В одном случае надо получить заказ с суммой, в другом сумма нафиг не нужна, а в третьем вовсе надо сгруппировать по месяцам и суммы получить.
G>А в предметной области есть только "заказ" и все.
А если нет -- зачем вам аггрегат, если он заведомо не нужен?
Те примеры, что вы привели, похожи на reporting. Выборка маппится на reporting items (dto), которые потом отдаются -- клиенту или UI.

Давайте я поясню, что ли по двум этим вопросам. Мне кажется, я понял, что вы хотите уточнить. Вы опасаетесь, что rich тянет много из БД -- вместо отдельных полей подтягивает весь объект и т.д. Такое в целом имеет место быть -- при использовании rich запросы получаются тяжелее (тянут больше данных), но на практике опасения не оправдываются по следующим причинам:
0) выборка 2х полей осуществляется практически с той же скоростью, что и выборка 20 (проверено на практике);
1) за счет объектного кеша такие запросы становятся крайне редки, потому что все данные уже тут;
2) правильно настроенный LL и прочая инфраструктура позволяет минимизировать обращения к БД;

Как-то так.
Re[22]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 15:04
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>Хм, надеюсь, я понял вас правильно. Результат выборки мапится на объект, которому потребовался срез. Чаще всего это UI DTO или Reporting DTO, или просто plain data (в этом случае никуда не мапится).


M>Те примеры, что вы привели, похожи на reporting. Выборка маппится на reporting items (dto), которые потом отдаются -- клиенту или UI.


Ну где же тут rich?

M>Давайте я поясню, что ли по двум этим вопросам. Мне кажется, я понял, что вы хотите уточнить. Вы опасаетесь, что rich тянет много из БД -- вместо отдельных полей подтягивает весь объект и т.д. Такое в целом имеет место быть -- при использовании rich запросы получаются тяжелее (тянут больше данных), но на практике опасения не оправдываются по следующим причинам:

M>0) выборка 2х полей осуществляется практически с той же скоростью, что и выборка 20 (проверено на практике);
Ну это смотря какие поля. Если джойнится несколько таблиц, то там может быть гораздо больше полей, чем 20. Если нужны только два из них остальные тянуть не стоит. Особенно по сети.

M>1) за счет объектного кеша такие запросы становятся крайне редки, потому что все данные уже тут;

M>2) правильно настроенный LL и прочая инфраструктура позволяет минимизировать обращения к БД;
Зачем создавать проблемы, а потом их геройски решать с помощью объектных кешей, и настройки LL, если можно просто получить необходимые данные сразу?
А уж если база действительно начнет загибаться, то кешировать результаты выборки, а еще лучше кешировать presentation entities или ответ на клиенте.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 15:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Посмотрел внутренности, оказалось что в безобидном на вид методе (типа AddItem) было обращение к дочерней коллекции, которая подтягивалась лениво.

G>>>А так как был зайдействован Linq2SQL, то он тянул всю коллекцию связнынх объектов на каждое обращение. И метод этот вызывался в цикле.
G>>>Отключение LL и загрузка только нужных данных дала офигенный прирост производительности. Для этого понадобилость только 3 строчки написать.

M>>Имхо вы тут путаетесь. Как LL может повлиять на то, что в цикле будут вытягиваться лишние данные? Как он может повлиять на то, что по каждому обращению данные будут вытягиваться заново из БД (объектный 2хуровневый кеш таки рулит(?

M>>ИМХО то, что linq2sql не дает настроить batch size loading в LL еще не значит, что LL -- это плохо и тормозно.

G>Еще раз если не заметили: проблема была исправлена тремя строчками с указанием явной загрузки нужных данных. Без двухуровневых объектных кешей и прочей лабуды.

А может, тогда на ассемблер всем, а?
В вашей ситуации, естественно, надо было выбирать исправление по обстоятельствам, что вы и сделали.

G>Кстати как кеш обеспечивает когерентность в условиях работы нескольких приложений с одной базой (без общего кеша)? или просто при использовании ХП?

Подмножеством методов, используемых в случае распределенного кеша: инвалидация кеша (полуавтоматическая, по таймауту или оповещениям с БД), маркировка областей кеша.
В целом, при работе нескольких приложений (кластер как частный случай) с одной БД следует использовать общий распределенный кеш, чтобы не настраивать вручную параметры инвалидации кеша во избежание "заезда" в регион устаревших данных.
Re[23]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 15:14
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>1) за счет объектного кеша такие запросы становятся крайне редки, потому что все данные уже тут;

M>>2) правильно настроенный LL и прочая инфраструктура позволяет минимизировать обращения к БД;
G>Зачем создавать проблемы, а потом их геройски решать с помощью объектных кешей, и настройки LL, если можно просто получить необходимые данные сразу?
G>А уж если база действительно начнет загибаться, то кешировать результаты выборки, а еще лучше кешировать presentation entities или ответ на клиенте.

Это тоже у нас кешируется, не переживайте -- и результаты выборки (cached query в NHibernate), и ответ на клиенте и для клиента. Другое дело, что последние к инфраструктуре persistence не относятся.
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Воронков Василий Россия  
Дата: 31.05.09 15:24
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>Ну это получится сервис в терминах anemic — класс содержащий логику обработки данных, и не содержащий самих данных.


Это будет не сервис в каких бы то ни было терминах. Это будет класс, представляющий собой ту или иную вполне предметную абстракцию. Вместо Товар.ПолучитьСкидку() имеем сущности Товар и Скидка — и так далее.

G>А если детально проанализировать предметную область, то окажется что очень мало объектов на самом деле обладают поведением.


Если в твоей предметной области мало объектов, которые обладают поведением, то значит жирная модель тебе не нужна. А вот в моей предметной области таких объектов много.

ВВ>>>>А если организацию при создании параметризировать сервисом, вызов в который она будет делегировать для получения списка емплоееров?

G>>>Это будет уже идиотизм. Так как сущности окажутся привязаны к сервисам без необходимости. А в остальном код такой же как в anemic будет.

ВВ>>Вот когда придет понимание, что привязка сущностей к сервисам куда лучше лучше чем зависимость сервисов от контрактов сущностей — что противоречит даже большинству сервис-ориентед паттернов — тогда и станет понятно, чем хороша жирная модель.


G>Давай в коде.

G>ты предлагаешшь:

Я предлагаю:
— размещать в классах только ту логику, которая непосредственно завязана на эти классы, которая является, скажем так, сущностной характеристикой класса. Будет ли эта логика прописана непосредственно в методах класса или во внешнем классе — вообще без разницы.
— не размещать в классах логику доступа к данным. Для этого существует упоминавшаяся выше инфраструктура (или Репозиторий у Фаулера). Кстати, приведенный тобой пример как раз очень даже напоминает работу с репозиторием.

G>В моем связность меньше. При этом еще код repository проще будет.

G>Что не так?

1. Код репозитория будет одинаков в обоих случах вообще-то
2. Связности меньше между чем и чем? Ты серьезно считаешь, что заменив вполне логичное Организация.ПолучитьСотрудников на ПолучитьСотрудников(Организация) ты решил какую-то серьезную проблему?

Ну давай разберемся.
Положим, у нас есть некий сервис, возвращающий сотрудников. Что еще делает этот сервис? Согласно каким принципам мы будем группировать функции в сервисы?
Далее — этот сервис зависит от внешних метаданных. Что уже плохо само по себе. Если мы не хотим помимо этого получить еще и кучу внешних зависимостей от других сервисов — что уже совсем как-то странно — нам придется все-все-все, что хоть как-то связано с сотрудниками и организациями (а может быть еще и с ролями, и с департаментами и пр.) — запихать в один сервис. А приложение у нас — ну скажем, орг-структура. Т.е. фактически вся логика в одном сервисе. Ну нормально.
Далее — нужно добавить новый метод — ПолучитьМенеджеров или что-то в этом роде, неважно. Что мы делаем? Дописываем новый метод в сервис? Ну это тоже совсем уж странно как-то. Умные люди говорят — надо новый сервис делать. Хорошо — новый так новый. Через неделю еще пару методов. Опять новый сервис?
Пять лет наша система поработала. На что она похожа через пять лет? Правильно. Зажимаем нос, проходим дальше.

И это банальный в общем-то пример. Орг-структура какая-то. А как быть с системами, в которых тысячи бизнес-сущностей. Вполне из жизни, кстати. Вот есть некоторая организация, которая собирает статистические данные — причем они у нее начинаются с уровня Государства и кончаются уровнем... Комната. Таким же макаром будем сервисы лепить?

В итоге — мне честно уже неясно — а ради чего все это? Ну выделили логику в сервис, ну отлично, а дальше что? Делаем вид, что убрали зависимости. По-моему наоборот — потенциально зависимости усилили. И на кой этот сервис в таком виде-то? Нормальный паттерн — тот же СОА — на таких сервисах не построишь. Полиморфизм идет лесом. Так смысл?
Re[8]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 15:46
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>>>Посмотрел внутренности, оказалось что в безобидном на вид методе (типа AddItem) было обращение к дочерней коллекции, которая подтягивалась лениво.

G>>>>А так как был зайдействован Linq2SQL, то он тянул всю коллекцию связнынх объектов на каждое обращение. И метод этот вызывался в цикле.
G>>>>Отключение LL и загрузка только нужных данных дала офигенный прирост производительности. Для этого понадобилость только 3 строчки написать.

M>>>Имхо вы тут путаетесь. Как LL может повлиять на то, что в цикле будут вытягиваться лишние данные? Как он может повлиять на то, что по каждому обращению данные будут вытягиваться заново из БД (объектный 2хуровневый кеш таки рулит(?

M>>>ИМХО то, что linq2sql не дает настроить batch size loading в LL еще не значит, что LL -- это плохо и тормозно.

G>>Еще раз если не заметили: проблема была исправлена тремя строчками с указанием явной загрузки нужных данных. Без двухуровневых объектных кешей и прочей лабуды.

M>А может, тогда на ассемблер всем, а?
Причем тут это?

M>В вашей ситуации, естественно, надо было выбирать исправление по обстоятельствам, что вы и сделали.

Ну так если весь код так писать он получится и быстрым и без огромного кеша.

G>>Кстати как кеш обеспечивает когерентность в условиях работы нескольких приложений с одной базой (без общего кеша)? или просто при использовании ХП?

M>Подмножеством методов, используемых в случае распределенного кеша: инвалидация кеша (полуавтоматическая, по таймауту или оповещениям с БД), маркировка областей кеша.
M>В целом, при работе нескольких приложений (кластер как частный случай) с одной БД следует использовать общий распределенный кеш, чтобы не настраивать вручную параметры инвалидации кеша во избежание "заезда" в регион устаревших данных.
То есть предлагаете вместе с БД держать еще клатер для кеша? Очень круто.
Re[6]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 16:01
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Здравствуйте, gandjustas, Вы писали:


G>>Ну это получится сервис в терминах anemic — класс содержащий логику обработки данных, и не содержащий самих данных.


ВВ>Это будет не сервис в каких бы то ни было терминах. Это будет класс, представляющий собой ту или иную вполне предметную абстракцию. Вместо Товар.ПолучитьСкидку() имеем сущности Товар и Скидка — и так далее.

Так он будет данные содержать или нет?

G>>А если детально проанализировать предметную область, то окажется что очень мало объектов на самом деле обладают поведением.


ВВ>Если в твоей предметной области мало объектов, которые обладают поведением, то значит жирная модель тебе не нужна. А вот в моей предметной области таких объектов много.

Пример? Какие персистентные объекты в твоей предметной области обладают плведением?

ВВ>>>>>А если организацию при создании параметризировать сервисом, вызов в который она будет делегировать для получения списка емплоееров?

G>>>>Это будет уже идиотизм. Так как сущности окажутся привязаны к сервисам без необходимости. А в остальном код такой же как в anemic будет.

ВВ>>>Вот когда придет понимание, что привязка сущностей к сервисам куда лучше лучше чем зависимость сервисов от контрактов сущностей — что противоречит даже большинству сервис-ориентед паттернов — тогда и станет понятно, чем хороша жирная модель.


G>>Давай в коде.

G>>ты предлагаешшь:

ВВ>Я предлагаю:

ВВ>- размещать в классах только ту логику, которая непосредственно завязана на эти классы, которая является, скажем так, сущностной характеристикой класса. Будет ли эта логика прописана непосредственно в методах класса или во внешнем классе — вообще без разницы.
Давай в коде. А то я совсем не представляю что такое "сущностная характеристика класса".

ВВ>- не размещать в классах логику доступа к данным. Для этого существует упоминавшаяся выше инфраструктура (или Репозиторий у Фаулера). Кстати, приведенный тобой пример как раз очень даже напоминает работу с репозиторием.

Там вообще-то и есть репозиторй.

G>>В моем связность меньше. При этом еще код repository проще будет.

G>>Что не так?

ВВ>1. Код репозитория будет одинаков в обоих случах вообще-то

Нет. В твоем случае репозиторй занимается DI, для создаваемых объектов. Это далеко нетривиальный код.
В соем случае может быть использован generic-класс для репозитория. в 60 строк вместе с комментами (я такой и использую).

ВВ>2. Связности меньше между чем и чем? Ты серьезно считаешь, что заменив вполне логичное Организация.ПолучитьСотрудников на ПолучитьСотрудников(Организация) ты решил какую-то серьезную проблему?

Это тебя не туда занесло. Нету у меня такого как Организация.ПолучитьСотрудников на ПолучитьСотрудников(Организация). У меня есть возможность получить сотрудников вместе с организацией или полуить сотрудников для организации заданной ключом.

ВВ>Ну давай разберемся.

ВВ>Положим, у нас есть некий сервис, возвращающий сотрудников. Что еще делает этот сервис? Согласно каким принципам мы будем группировать функции в сервисы?
ВВ>Далее — этот сервис зависит от внешних метаданных. Что уже плохо само по себе. Если мы не хотим помимо этого получить еще и кучу внешних зависимостей от других сервисов — что уже совсем как-то странно — нам придется все-все-все, что хоть как-то связано с сотрудниками и организациями (а может быть еще и с ролями, и с департаментами и пр.) — запихать в один сервис. А приложение у нас — ну скажем, орг-структура. Т.е. фактически вся логика в одном сервисе. Ну нормально.
ВВ>Далее — нужно добавить новый метод — ПолучитьМенеджеров или что-то в этом роде, неважно. Что мы делаем? Дописываем новый метод в сервис? Ну это тоже совсем уж странно как-то. Умные люди говорят — надо новый сервис делать. Хорошо — новый так новый. Через неделю еще пару методов. Опять новый сервис?
ВВ>Пять лет наша система поработала. На что она похожа через пять лет? Правильно. Зажимаем нос, проходим дальше.

ВВ>И это банальный в общем-то пример. Орг-структура какая-то. А как быть с системами, в которых тысячи бизнес-сущностей. Вполне из жизни, кстати. Вот есть некоторая организация, которая собирает статистические данные — причем они у нее начинаются с уровня Государства и кончаются уровнем... Комната. Таким же макаром будем сервисы лепить?


ВВ>В итоге — мне честно уже неясно — а ради чего все это? Ну выделили логику в сервис, ну отлично, а дальше что? Делаем вид, что убрали зависимости. По-моему наоборот — потенциально зависимости усилили. И на кой этот сервис в таком виде-то? Нормальный паттерн — тот же СОА — на таких сервисах не построишь. Полиморфизм идет лесом. Так смысл?


Не туда тебя занесло. Не должна БЛ занимться получением связанных данных.
Это ты сам выдумал, а теперь сам же и опровеграешь.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 16:06
Оценка:
Здравствуйте, gandjustas, Вы писали:
ВВ>>2. Связности меньше между чем и чем? Ты серьезно считаешь, что заменив вполне логичное Организация.ПолучитьСотрудников на ПолучитьСотрудников(Организация) ты решил какую-то серьезную проблему?
G>Это тебя не туда занесло. Нету у меня такого как Организация.ПолучитьСотрудников на ПолучитьСотрудников(Организация). У меня есть возможность получить сотрудников вместе с организацией или полуить сотрудников для организации заданной ключом.

Забыл уточнить. Это часть persistance инфраструктуры и к БЛ отношения не имеет.
Re[5]: Anemic Domain Model vs Rich Domain Model
От: Mike Chaliy Украина http://chaliy.name
Дата: 31.05.09 16:35
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Что не так?


Твой код не компилиться .
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
А тут я живу и пишу...
Re[9]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 31.05.09 16:45
Оценка:
Здравствуйте, gandjustas, Вы писали:

M>>В вашей ситуации, естественно, надо было выбирать исправление по обстоятельствам, что вы и сделали.

G>Ну так если весь код так писать он получится и быстрым и без огромного кеша.
Значит, LL в Linq2SQL придумали зря
Еще раз говорю, кеш огромен, потому что данных много.

G>>>Кстати как кеш обеспечивает когерентность в условиях работы нескольких приложений с одной базой (без общего кеша)? или просто при использовании ХП?

M>>Подмножеством методов, используемых в случае распределенного кеша: инвалидация кеша (полуавтоматическая, по таймауту или оповещениям с БД), маркировка областей кеша.
M>>В целом, при работе нескольких приложений (кластер как частный случай) с одной БД следует использовать общий распределенный кеш, чтобы не настраивать вручную параметры инвалидации кеша во избежание "заезда" в регион устаревших данных.
G>То есть предлагаете вместе с БД держать еще клатер для кеша? Очень круто.
Причем здесь кластер под кеш? В минимальном случае запускаете на машине сервис кеширования и все, хоть на той же, где БД, хоть на сервере приложений. Нужно 2 аппаратных узла -- запускаете на 2х машинах. Сервис кеширования в простейшем виде -- огромная распределенная хэш-таблица с автоматическим определением вышедших из строя узлов. В более сложном -- in-memory data grid с репликацией. Но кластер необязателен в любом случае.
Re[7]: Anemic Domain Model vs Rich Domain Model
От: Лобанов Игорь  
Дата: 31.05.09 16:49
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>Здравствуйте, gandjustas, Вы писали:


G>>>Здравствуйте, Лобанов Игорь, Вы писали:


ЛИ>>>>В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.


G>>>Очень наивно так полагать.


ЛИ>>Я всё же предлагаю разделять случаи, когда "должно, но не работает" и "в принципе не должно". Первое лечится багфиксингом, второе -- нет.


G>LL создает условия возникновения таких ошибок.


Жизнь вообще вредная штука, от неё умирают
Re[10]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 31.05.09 20:16
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>>>В вашей ситуации, естественно, надо было выбирать исправление по обстоятельствам, что вы и сделали.

G>>Ну так если весь код так писать он получится и быстрым и без огромного кеша.
M>Значит, LL в Linq2SQL придумали зря
Не зря. Фреймворк должен давать все способы работы. А вот включили по-умолчанию зря.

M>Еще раз говорю, кеш огромен, потому что данных много.

Большое кол-во данных не означает что должен быть большим кеш.

G>>>>Кстати как кеш обеспечивает когерентность в условиях работы нескольких приложений с одной базой (без общего кеша)? или просто при использовании ХП?

M>>>Подмножеством методов, используемых в случае распределенного кеша: инвалидация кеша (полуавтоматическая, по таймауту или оповещениям с БД), маркировка областей кеша.
M>>>В целом, при работе нескольких приложений (кластер как частный случай) с одной БД следует использовать общий распределенный кеш, чтобы не настраивать вручную параметры инвалидации кеша во избежание "заезда" в регион устаревших данных.
G>>То есть предлагаете вместе с БД держать еще клатер для кеша? Очень круто.
M>Причем здесь кластер под кеш? В минимальном случае запускаете на машине сервис кеширования и все, хоть на той же, где БД, хоть на сервере приложений. Нужно 2 аппаратных узла -- запускаете на 2х машинах. Сервис кеширования в простейшем виде -- огромная распределенная хэш-таблица с автоматическим определением вышедших из строя узлов. В более сложном -- in-memory data grid с репликацией. Но кластер необязателен в любом случае.
Я знаю как системы кеширования запускать. Вопрос не в этом.
Вопрос в том что фактически вместе с базой еще надо и навороченный кеш держать, чтобы rich мог работать на большом количестве данных.
Re[15]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 01.06.09 00:56
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Я его читал. Я предлагаю не рассматривать"предметную область" как вещь в себе.

G>Ведь в конченом итоге надо сделать приложение, которое полезно людям, а не модель некоторой предметной области.

Гммм... а тогда с чем вы не согласны? Эванс всё классно расписал про место предметной области. Это ничуть не новая идея, и ни разу не панацея. Эванс просто неплохой популяризатор, да и время удачно совпало.

S>>Ещё такое ощущение, что у вас разработка заканчивается с впариванием результатов заказчику — там такой подход конеш рулит.

G>Не совсем "впариваением", но смысл именно такой — чтобы заказчик был доволен.

А.. Ну здесь уже начинается сложная философская беседа о том как кого сделать довольным. У нас всё проще: заплатили деньги -> ???-> классный товар. Потому что поддерживать сможем только мы. А себя обламывать не хочется. Я ведь угадал нечаянно — у нас разные в принципе подходы к разработке ПО. И то что я тут вам пропагандирую, для вас никакой ценности не имеет. В итоге пора закругляться, на всякий отвечу на остальное.




G>Это зависит от закачика и от менеджера.

...
Ну да. И ни одна методика не будет работать с другими людьми. Потому что человек, которому абсолютно ничего не надо — самая вредная вещь в команде.

S>>Скажите, как вообще можно строить дизайн системы на основе функциональных требований?

G>Рецепты давно известны: слабая связность и следовать принципам KISS и YAGNI.
Дык это противоположность — мы пытаемся ослабить влияние дизайна на поддерживаемость программы. Вместо того чтобы "сидеть и наслаждаться", мы предпринимаем кучу усилий чтобы исправить свои прошлые ошибки.

Слабая связность рулит , но когда KISS и YAGNI понимают как "потом сделаю"... Не будет этого потом. Если нужно сделать что-то качественно — это надо делать сразу, с углублением в контекст и т.п. Куча мелких серий "час лепим одно, час-другое, потом возвращаемся" отвратительно влияет на код из-за банального выноса стека в мозге. Это тоже всё как бы общеизвестно...

S>>Они же описывают только внешний интерфейс системы. Всё что вы можете сделать — провести кластеризацию графа зависимостей и выделить компоненты по степени связности. Этот дизайн нифига не будет стабильным — любое новое требование перекроит все зависимости и дизайн, заточенный под конкретный набор юз-кейзов будет только мешать развивать систему.

G>Далеко не так. Ведь у нас есть не только пожелания заказчика, а есть еще и требования от предметной области.
G>Стартовый набор требований обычно достаточно большой, чтобы большая часть системы оставалась стабильной при всех изменениях.
Ну да. Вы сейчас сказали то что я от вас всю эту беседу добивался. Остался один логический шаг — информацию о предметной области можно использовать не только для дизайна, но и в обсуждениях функционала программы etc. Ну и естественно надо отделить объективную информацию от субъективных требований заказчика.

G>Угу Ubiquitous Language, проходили уже. А толку от него? Ну поговорили вы со специалистами на их языке, сделали требования корректныим.

G>Как это на дизайн приложения повлияет.

А тут два варианта — либо я вам щас проповедь закачу, либо скажу что влияет на стиль мышления: минимум терминов, всем в команде всё понятно (раздражает когда где-то в середине разработки выясняется что никто в предметной области не рубит), наличие одной модели позволяет выловить её косяки/косяки в требованиях. Обсуждать всё проще на порядок. Причём польза и заказчику — люди с таким удивлением обнаруживаю что у них бардак, так радуются что нашли где косяки, что аж приятно становится

Самая главная фича — изначально видны требования к структуре данных, и примерно видны правила по которым будет работать логика приложения. Фундамент есть с самого начала. Причём даром, т.е. практически безвозмездно(с).

S>>Ну и в подарок получаете дизайн устойчивый к самым неожиданным требованиям.

G>Если бы все было так хорошо, как на словах, то все бы давно использовали DDD.
G>Вот только DDD начинает отсасывать даже тогда, когда просто требуется добавить нетривиальную экранную форму для каких-либо целей.

А вы не путайте идею и то как Эванс её трактует. Он во второй части книги ни разу не следует самому себе — громадный репозитарий со всеми зависимостями и логикой там же. Это ж полный убиццаобстену. Но если включить мозги (с) ваше.

G>Вот становится весело, когда новые требования не укладываются в модель.

G>Например была какая-то банальная торговая система, а тут потребовалось внести возможность резервирования и предзаказа.

Гммм... в банальной торговой системе с самого начала известно что это ERM. Тут те фичи, что вы написали — как раз очевидные требования. Но да, бывает весело. Зато затронут изменения только ту часть системы что работает с товаром — слабая связность получается почти искаробки.

Спасибо, было очень приятно пообщаться
Re[22]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 06:48
Оценка:
Здравствуйте, meowth, Вы писали:

M>Давайте я поясню, что ли по двум этим вопросам. Мне кажется, я понял, что вы хотите уточнить. Вы опасаетесь, что rich тянет много из БД -- вместо отдельных полей подтягивает весь объект и т.д. Такое в целом имеет место быть -- при использовании rich запросы получаются тяжелее (тянут больше данных), но на практике опасения не оправдываются по следующим причинам:

M>0) выборка 2х полей осуществляется практически с той же скоростью, что и выборка 20 (проверено на практике);
Это какая-то очень-очень нестандартная практика. Систематическое тестирование различных сценариев доступа к данным показывает, что себестоимость запросов очень сильно зависит от набора полей в выбранной проекции. Если это не так — то скорее всего у вас боттлнек где-то еще. Либо, что тоже возможно, на базу ни разу не смотрел вменяемый DBA. Например, в таблицах нет индексов (кроме тех, которые автоматически сгенерил ORM).
M>1) за счет объектного кеша такие запросы становятся крайне редки, потому что все данные уже тут;
Объектный кэш не уменьшает количество запросов. Он просто позволяет вам некоторое время делать вид, что их нету. Например, провоцируя замену нормальных декларативных способов описания связей объектов прямыми ссылками — чтобы можно было пользоваться навигацией вместо запросов. Что масштабируется хуже, чем SQL.

M>2) правильно настроенный LL и прочая инфраструктура позволяет минимизировать обращения к БД;

LL не может помочь минимизировать обращения к БД. Всё, что он делает — оттягивает момент неизбежного обращения к БД насколько возможно. Минимизация обращений возможна только при eager load, который за 1 обращение достаёт все нужные данные сразу.

M>Как-то так.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 06:48
Оценка: +1
Здравствуйте, meowth, Вы писали:

M>Ой, какие нехорошие кеши, путаются все время

M>У меня кластер из серверов приложений, ничего не путаются. Наверное, потому, что shared cache, как делают все разработчики, использующие фермы.
Это всё замечательно. Вот только если бы вы выкинули нахрен ваш кэш, и развернули бы на том же железе чистое stateless-приложение с анемичной моделью поверх RDBMS, то совершенно на ровном месте получили бы рост throughput если не на порядок, то на полпорядка точно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 07:02
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, gandjustas, Вы писали:


G>>Я его читал. Я предлагаю не рассматривать"предметную область" как вещь в себе.

G>>Ведь в конченом итоге надо сделать приложение, которое полезно людям, а не модель некоторой предметной области.

S>Гммм... а тогда с чем вы не согласны? Эванс всё классно расписал про место предметной области. Это ничуть не новая идея, и ни разу не панацея. Эванс просто неплохой популяризатор, да и время удачно совпало.


Не согласен с тем что такой подход стоит применять при дизайне программы. Он хорош для анализа, не более того.


S>>>Скажите, как вообще можно строить дизайн системы на основе функциональных требований?

G>>Рецепты давно известны: слабая связность и следовать принципам KISS и YAGNI.
S>Дык это противоположность — мы пытаемся ослабить влияние дизайна на поддерживаемость программы. Вместо того чтобы "сидеть и наслаждаться", мы предпринимаем кучу усилий чтобы исправить свои прошлые ошибки.
И каким образом вы его пытаетесь ослабить? Написав больше кода? Не поможет. Чем больше кода, тем сложнее вносить изменения.

S>Слабая связность рулит , но когда KISS и YAGNI понимают как "потом сделаю"... Не будет этого потом.

Нет. YAGNI нужно понимать буквально: "это сейчас не нужно". А KISS означает что все что делается нужно делать наиболее простым способом.

S>>>Они же описывают только внешний интерфейс системы. Всё что вы можете сделать — провести кластеризацию графа зависимостей и выделить компоненты по степени связности. Этот дизайн нифига не будет стабильным — любое новое требование перекроит все зависимости и дизайн, заточенный под конкретный набор юз-кейзов будет только мешать развивать систему.

G>>Далеко не так. Ведь у нас есть не только пожелания заказчика, а есть еще и требования от предметной области.
G>>Стартовый набор требований обычно достаточно большой, чтобы большая часть системы оставалась стабильной при всех изменениях.
S>Ну да. Вы сейчас сказали то что я от вас всю эту беседу добивался. Остался один логический шаг — информацию о предметной области можно использовать не только для дизайна, но и в обсуждениях функционала программы etc. Ну и естественно надо отделить объективную информацию от субъективных требований заказчика.
Для функционала программи пофиг откуда требования.

G>>Угу Ubiquitous Language, проходили уже. А толку от него? Ну поговорили вы со специалистами на их языке, сделали требования корректныим.

G>>Как это на дизайн приложения повлияет.

S>А тут два варианта — либо я вам щас проповедь закачу, либо скажу что влияет на стиль мышления: минимум терминов, всем в команде всё понятно (раздражает когда где-то в середине разработки выясняется что никто в предметной области не рубит), наличие одной модели позволяет выловить её косяки/косяки в требованиях. Обсуждать всё проще на порядок. Причём польза и заказчику — люди с таким удивлением обнаруживаю что у них бардак, так радуются что нашли где косяки, что аж приятно становится

Это все относится к анализу требований. Совершенно не следует эти знания явно выражать в коде в виде объектов.

S>Самая главная фича — изначально видны требования к структуре данных, и примерно видны правила по которым будет работать логика приложения. Фундамент есть с самого начала. Причём даром, т.е. практически безвозмездно(с).

Это как раз плохо. Структура данных должна соответствовать функционалу системы, а не быть вещью в себе.
Надавно в соседней теме кто-то хотел иметь структуру дерева в БЛ, со всеми древесными операциями. Я расписал какие функции от этого дерева потребуются на примере иерархического форума. Оказалось что обобщенное дерево совершенно не нужно.
Re[8]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 07:05
Оценка:
Здравствуйте, meowth, Вы писали:
G>>Не выдумывай. Я не написал что мешают все средства, мешают только некоторые, такие как LL например.
M>В другом посте вы сказали, что для anemic тоже есть инфраструктура, обеспечивающая persistence ignorance. LL -- это ее важная часть. А тут вдруг оказывается, что LL -- мешает. Интересная у вас логика. Об ее "жестокуюю реальность" "разбивается" моя точка зрения )
Еще раз: не надо путать похожие вещи. LL — это важная часть ignorant persistence, а не persistence ignorance.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Anemic Domain Model vs Rich Domain Model
От: Sinix  
Дата: 01.06.09 07:14
Оценка:
Здравствуйте, gandjustas

Я ж говорю — у нас разная ситуация, поэтому спорить бессмысленно. Я кучу раз приводил по пунктам что даёт модель предметной области. Вы всё это отметаете одним "это не нужно". Ну напишу я ещё раз, вы ещё раз скажете что всё неверно... Изменится что-нить?

Завязываю.
Re[23]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 07:24
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>LL не может помочь минимизировать обращения к БД. Всё, что он делает — оттягивает момент неизбежного обращения к БД насколько возможно. Минимизация обращений возможна только при eager load, который за 1 обращение достаёт все нужные данные сразу.


1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД? А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.
Re[17]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 07:41
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, meowth, Вы писали:


M>>Ой, какие нехорошие кеши, путаются все время

M>>У меня кластер из серверов приложений, ничего не путаются. Наверное, потому, что shared cache, как делают все разработчики, использующие фермы.
S>Это всё замечательно. Вот только если бы вы выкинули нахрен ваш кэш, и развернули бы на том же железе чистое stateless-приложение с анемичной моделью поверх RDBMS, то совершенно на ровном месте получили бы рост throughput если не на порядок, то на полпорядка точно.

Ух ты, еще один анимист-экстрасенс А диагноз по фотографии вы не ставите?

Не обижайтесь +) Сколько у вас MsSQL транзакций в секунду делает, если не секрет? Ну так, чтобы thru-put соизмерить.
ИМХО если не будет кеша, однозначно растет количество запросов в БД, которая является слабым местом системы. Stateless или statefull -- это уже другой вопрос.
Re[17]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 07:44
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это всё замечательно. Вот только если бы вы выкинули нахрен ваш кэш, и развернули бы на том же железе чистое stateless-приложение с анемичной моделью поверх RDBMS, то совершенно на ровном месте получили бы рост throughput если не на порядок, то на полпорядка точно.


Вот мы сначала так и сделали. Оказалось, что кешировать редко изменяемые сущности и запросы очень выгодно.

Да и вообше, практически все, кто пишет о высоких нагрузках, большое значение уделяют именно кешам.
Re[18]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 07:50
Оценка: :)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, gandjustas


S>Я ж говорю — у нас разная ситуация, поэтому спорить бессмысленно. Я кучу раз приводил по пунктам что даёт модель предметной области. Вы всё это отметаете одним "это не нужно". Ну напишу я ещё раз, вы ещё раз скажете что всё неверно... Изменится что-нить?

Так это действительно не нужно.
Преимущества, описываемые вам — мнительные. Хорошее приложение можно и без них написать.
Re[24]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 07:53
Оценка: +1
Здравствуйте, WFrag, Вы писали:

WF>Здравствуйте, Sinclair, Вы писали:


S>>LL не может помочь минимизировать обращения к БД. Всё, что он делает — оттягивает момент неизбежного обращения к БД насколько возможно. Минимизация обращений возможна только при eager load, который за 1 обращение достаёт все нужные данные сразу.


WF>1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД? А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.


Такое работает только для справочных данных. Их вообще можно кешировать на клиенте.
Re[18]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 07:59
Оценка:
Здравствуйте, meowth, Вы писали:

M>ИМХО если не будет кеша, однозначно растет количество запросов в БД, которая является слабым местом системы.

БД является слабым местом если приложение неэффективно работает с ней. Синклер говорит (имхо небезосновательно) что можно написать приложение так, что вы будете не состоянии одинм аппсервером закормить БД, и не применять при этом распределенный кеш с кешированием результатов запросов.
Re[23]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 08:00
Оценка:
Здравствуйте, Sinclair, Вы писали:

M>>0) выборка 2х полей осуществляется практически с той же скоростью, что и выборка 20 (проверено на практике);

S>Это какая-то очень-очень нестандартная практика. Систематическое тестирование различных сценариев доступа к данным показывает, что себестоимость запросов очень сильно зависит от набора полей в выбранной проекции. Если это не так — то скорее всего у вас боттлнек где-то еще. Либо, что тоже возможно, на базу ни разу не смотрел вменяемый DBA. Например, в таблицах нет индексов (кроме тех, которые автоматически сгенерил ORM).
M>>1) за счет объектного кеша такие запросы становятся крайне редки, потому что все данные уже тут;
S>Объектный кэш не уменьшает количество запросов. Он просто позволяет вам некоторое время делать вид, что их нету. Например, провоцируя замену нормальных декларативных способов описания связей объектов прямыми ссылками — чтобы можно было пользоваться навигацией вместо запросов.
S>Что масштабируется хуже, чем SQL.

а)Объектный кеш позволяет перераспределить запросы во времени и снять нагрузку с БД по выборке данных. Странно, что вы с этим спорите.
б)"декларативных способов описания связей объектов" -- вы не связи объектов таким образом описываете, а связи записей в БД, т.е. элементов множеств. Это разные вещи.

M>>2) правильно настроенный LL и прочая инфраструктура позволяет минимизировать обращения к БД;

S>LL не может помочь минимизировать обращения к БД. Всё, что он делает — оттягивает момент неизбежного обращения к БД насколько возможно. Минимизация обращений возможна только при eager load, который за 1 обращение достаёт все нужные данные сразу.
ИМХО вы меня не поняли. Там была жалоба на то, что LL увеличивает количество обращений к БД до неприличного в случае коллекций. А я говорил, что правильно настроенный lazy load может вытягивать эту коллекцию batch-ем -- скажем, 30 айтемов за 3 раза, а кроме того -- брать ее из кеша.
Re[18]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 08:06
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>Здравствуйте, Sinclair, Вы писали:


S>>Это всё замечательно. Вот только если бы вы выкинули нахрен ваш кэш, и развернули бы на том же железе чистое stateless-приложение с анемичной моделью поверх RDBMS, то совершенно на ровном месте получили бы рост throughput если не на порядок, то на полпорядка точно.


WF>Вот мы сначала так и сделали. Оказалось, что кешировать редко изменяемые сущности и запросы очень выгодно.


WF>Да и вообше, практически все, кто пишет о высоких нагрузках, большое значение уделяют именно кешам.

Кеширование разным бывает.
Re[19]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 08:06
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, meowth, Вы писали:


M>>ИМХО если не будет кеша, однозначно растет количество запросов в БД, которая является слабым местом системы.

G>БД является слабым местом если приложение неэффективно работает с ней. Синклер говорит (имхо небезосновательно) что можно написать приложение так, что вы будете не состоянии одинм аппсервером закормить БД, и не применять при этом распределенный кеш с кешированием результатов запросов.

А он не говорит также случайно, сколько стоит написать такое сферическое приложение в вакууме и каковы его динамические и эволюционные характеристики?
Re[24]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 08:13
Оценка:
Здравствуйте, WFrag, Вы писали:
WF>1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД?
Я тебя уверяю — если одна часть хорошо кэшируется, СУБД об этом будет знать. И никакой чрезмерной нагрузки создавать не будет.
WF>А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.
Зачем нагружать СУБД задачей поддерживать актуальность этой связной сущности?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 08:13
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>Вот мы сначала так и сделали. Оказалось, что кешировать редко изменяемые сущности и запросы очень выгодно.

Ну так никто не мешает это сделать.
WF>Да и вообше, практически все, кто пишет о высоких нагрузках, большое значение уделяют именно кешам.
Правильно. Но только не LL-кэш, а нормальный кэш того, что нужно. На стороне СУБД кэшируются страницы данных — потому что это то, с чем работает СУБД. На стороне сервера приложений кэшируются результаты запросов к СУБД — потому, что это то, с чем работает сервер приложений.
На стороне клиента (и на пути к нему) кэшируются результаты запросов к серверу приложений — потому, что это то, с чем работает клиент.
Зачем нужно кэшировать какие-то искусственные сущности посредине — лично мне непонятно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 08:13
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, meowth, Вы писали:


M>>>ИМХО если не будет кеша, однозначно растет количество запросов в БД, которая является слабым местом системы.

G>>БД является слабым местом если приложение неэффективно работает с ней. Синклер говорит (имхо небезосновательно) что можно написать приложение так, что вы будете не состоянии одинм аппсервером закормить БД, и не применять при этом распределенный кеш с кешированием результатов запросов.

M>А он не говорит также случайно, сколько стоит написать такое сферическое приложение в вакууме и каковы его динамические и эволюционные характеристики?

Не дороже чем любое другое. Это уже я говорю.
Надо только головой думать на каждом этапе, от проектирования интерфейса до создания БД.
Re[19]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 08:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Правильно. Но только не LL-кэш, а нормальный кэш того, что нужно.


А если это совпадает, «нормальный» кэш и LL-кэш? См. пример ниже. Получается, ничего делать не нужно — только пару аннотаций навесить.

S>На стороне СУБД кэшируются страницы данных — потому что это то, с чем работает СУБД. На стороне сервера приложений кэшируются результаты запросов к СУБД — потому, что это то, с чем работает сервер приложений.


А если нужно (можно) кешировать только часть запроса? У нас есть две сущности, рейс и аэропорт. Кешировать результат запроса рейс+аэропорт смысла нет, рейс часто меняется, не хочется иметь проблем с синхронизацией кешей и БД. А вот аэропорт, сущность словарная, кешируется очень хорошо — по отдельности от рейса.

S>На стороне клиента (и на пути к нему) кэшируются результаты запросов к серверу приложений — потому, что это то, с чем работает клиент.

S>Зачем нужно кэшировать какие-то искусственные сущности посредине — лично мне непонятно.

Так это искусственная сущность и есть результат запроса (вернее, его часть). Нам нужно сгенерировать письмо с информацией по рейсу + аэропорт (какие именно данные потребуется мы не знаем — используются шаблоны). Выбираем из БД рейс с «ленивой» привязкой к аэропорту — и вуаля, в большинстве случаев выбираться будут только данные по рейсу. Что нам и нужно.
Re[25]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 08:28
Оценка:
Здравствуйте, gandjustas, Вы писали:

WF>>1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД? А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.


G>Такое работает только для справочных данных. Их вообще можно кешировать на клиенте.


Может, я вас не понял, но тут имхо вы не правы. До тех пор, пока кеш для связанных сущностей (например, коллекции дочерних сущностей) не был сброшен, для навигации внутри бизнес-логики они выбираются из кеша, т.к. навигация к ним осуществляется по id, а identity map отрабатывает эти моменты.
Re[18]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 08:30
Оценка: +1
Здравствуйте, meowth, Вы писали:

M>Не обижайтесь +) Сколько у вас MsSQL транзакций в секунду делает, если не секрет? Ну так, чтобы thru-put соизмерить.

Не очень понятно, зачем вас интересуют транзакции MsSQL. Надо смотреть на те транзакции, которые видят ваши клиенты.
Ну, если шибко интересно, сходите на tpc.org, поищите сопоставимое с вашим железо. Сравните свои результаты с "правильным ответом".

M>ИМХО если не будет кеша, однозначно растет количество запросов в БД, которая является слабым местом системы.

Да ладно. "Слабым местом системы"... Насмешили. Современную СУБД нагнуть крайне сложно. Если, конечно, не пытаться писать поперёк строчек.
Кэш в ORM введен не для того, чтобы стало хорошо, а чтобы не было совсем плохо — без него LL убивает систему на взлёте.
При этом анемичная модель никак не мешает грамотно прикрутить кэширование в нужных местах.
M>Stateless или statefull -- это уже другой вопрос.
Вопрос пока только один — зачем тратить ресурсы на поддержание когерентности кэша — когда уже есть одна вполне когерентная реплика внутри СУБД. Лучше добавить два гигабайта памяти в машину с SQL Server, чем отдать их небесплатному когерентному кэшу объектов в памяти.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 08:30
Оценка:
Здравствуйте, meowth, Вы писали:
M>А он не говорит также случайно, сколько стоит написать такое сферическое приложение в вакууме и каковы его динамические и эволюционные характеристики?
Конечно же, стоимость такого приложения ниже, чем в рич-модели. Потому, что не пишется лишнего кода.
Нет, я понимаю, что взрослые пацаны лишний код пишут не сами, а при помощи автогенераторов, но тем не менее.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[25]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 08:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Я тебя уверяю — если одна часть хорошо кэшируется, СУБД об этом будет знать. И никакой чрезмерной нагрузки создавать не будет.


Вот ты сам несколькими постами выше утверждал, что себестоимость запроса сильно зависит от набора полей. Зачем выбирать +N полей, если их можно взять из местного кеша? Да, можно было это делать явно. Загружаем «рейс», делаем запрос к кешу, выбираем «аэропорт», формируем текст сообщения по шпблону.

Но зачем, если проще просто объявить аэропорт связанной с рейсом сущностью, и пометить как «кешируемо»? А ORM всё сделает за нас.

WF>>А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.

S>Зачем нагружать СУБД задачей поддерживать актуальность этой связной сущности?

Не понял мысли. Предлагается вообще не хранить словарную сущность («аэропорт») в БД?
Re[26]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 08:41
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


WF>>>1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД? А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.


G>>Такое работает только для справочных данных. Их вообще можно кешировать на клиенте.


M>Может, я вас не понял, но тут имхо вы не правы. До тех пор, пока кеш для связанных сущностей (например, коллекции дочерних сущностей) не был сброшен, для навигации внутри бизнес-логики они выбираются из кеша, т.к. навигация к ним осуществляется по id, а identity map отрабатывает эти моменты.


Для этого никакой кеши не нужен. Достаточно один раз загрузить сущность со связанными (выполняется join) на запрос и потом ходить по связанным сущностям сколько влезет. При этом если кто-то другой в этот момент поменяет связанную колеекцию, то фантомов у вас не появится (оптимистичная блокировка против них бессильна).
Re[17]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Неправильно. Метрики правильности его применения. Это несколько другое.

Какое другое?

GZ>Ну надо же. Я же писал условия задачи, и тут оказывается что нет. Что ты в неагрегате собираешься хранить?

Ты условие задачи каждый раз подгоняешь. В неагрегате я собираюсь хранить всю информацию необходимую для проверки доступа, если уж ты в этот объект ее поместил.

GZ>Повторяю то что писал до этого. Если нам не хватает идентификатора, а нужно поднимать весь объект, то по ресурсоемкости задача равняется Rich. А вот по сопровождению — проигрывает.

Не проигрывает, а выигрывает. Собственно, на примере с солнцем это хорошо видно.

GZ>Если тебе нужно закрутить солнце в другую сторону, найди другую кнопку на солнце.

О, отлично! Теперь смотри:
Rich — разбираем солнце, прикручиваем к нему новую кнопку, собираем солнце обратно — кто даст гарантию, что не останутся лишние детали ?
Anemic — просто пользуемся двумя кнопками в обратном порядке и это явно описанный и предсказуемый эффект.
Так что в поддержке на самом деле оказывается проще?

GZ>Иначе не факт, что при обратной последовательности действий солнце не упадет на землю, и вконец не придавит слонов которые ее держат.

В том, то и дело, что факт, что не упадет и ничего сверх ожидаемого не произойдет. Потому что нет никакой магии и все делается явно, как это прописано в контракте. Никаких LL, прозрачных подргузок объектов по цепочке, передач неявных параметров и всего остального.

GZ>Ввод новой сигнатуры не обозначает отмену старой которая используется для других объектов.

Именно что озачает. У нас явно поменялся способ проверки безопасности, никаких старых не осталось.

GZ>Это уже вопрос ресурсоемкости а не дизайна.

Это именно вопрос дизайна, причем это один из основных вопросов дизайна.

GZ>Что такое object cohesion?

Ну ты бы хотя бы статью в википедии почитал (я правда сам запамятовал, официально она все же сommunicational cohesion)

GZ>Если тебе интересны подобные аналогии, то в Rich — распространен Data coupling, в Anemic — Control Coupling.

Это не аналогии, это формальная терминология.

GZ> Угадай, что лучше?

Ну ты собственные-то термины не изобретай.

GZ>Gang of Four — можешь подобрать любой способ.

Во-во, берешь в одну руку Rich, в другую банду четырех, применяешь одно к другому и получаешь Anemic..


GZ>Все, мило молчу. Тебе виднее.

Ясен байт виднее.

GZ>Опять. Если ты о контексте использования, то Gang of Four/

По GoF я уже скаазл.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[14]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Сорри, я наверное туплю. Но я просто вызываю эти методы. Замени слова ЭТО на что-то конкретное.

Ну, дурачком прикидываться ты, очевидно долго можешь..
Так что именно делают эти методы?

MC>Ты его просто не понимаеш. Если бы понял, все было бы к месту. но судя по всему я не смогу обьяснить.

Раз ты не можешь объяснить, зачит если ты это и понимаешь, то как-то не так. ))

MC> Уж не к своему пониманию СРП, про то что хранение данных это уже достаточная респонсибилити?

И к этому тоже, само собой.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>У нас практически не встречаеться.

У вас требования не меняются? Вы, ребята, явно в альтернативной реальности живете..

MC> У нас публикуеться минимум, у нас это один из принципов.

Ты эти мантры брось..

MC>Поэтому если что-то надо добавить для УИ, то никто не будет этого менять, в сервисах и наоборот.

Зашибись, а откуда оно у тебя в UI возьмется, если ты это в базу не положишь?

MC>Та не, ты привел какойто левый пример, я вообще ни слова притензий не сказал.

Тот факт, что пример опровергает твои утверждения, не означает, что он "левый".

MC>Могу попробовать написать средства которыми мы помогам себе чтобы изоляция не порвалась...

Что собственно и требовалось доказать — ваша волшебная изоляция, не достоинство модели, а заслуга средств, которые вы регулярно применяете. Ну так я тоже зубы каждый день чищу и они уменя целые и блестящие...

MC>К бизнес модели. Репортинг это не более чем еще одно ридонли представление данных. А данные у нас меняються тока в модели.

Ну, то есть, читаете вы из одного места, а пишите в другое. Можно и так, но обычно делают проще..

MC>?? Еще раз, мы не городим, у нас код получаеться значительно лаконичней, лучше документирован, лучше для изменения бизнес логики.

Лучше чем что? Или лучше чем как?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[10]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка:
Здравствуйте, Mike Chaliy, Вы писали:

MC>Хм, мы используем ее там где это оправдано.

Да кто бы спорил...

MC>Пля, ну и где я не ответил? Дава конкретный вопрос где я не ответил.

Да практически нигде, как друочку включил с самого начала, так только в последних постах что-то по делу стал писать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[16]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка: +1
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>А Вы используйте правильные кэши, которые дружат с кластером.

Ага, это назвается придумать себе проблемы, а потом героически их преодолевать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[4]: Anemic Domain Model vs Rich Domain Model
От: IB Австрия http://rsdn.ru
Дата: 01.06.09 08:44
Оценка: 1 (1) +2
Здравствуйте, Лобанов Игорь, Вы писали:

ЛИ>Делить не стоит, потому что не смотря на полную независимость иерархий, в каких-то сценариях потребуется навигация одновременно по двум иерархиям.

Зашибись винегрет. Ради одного частного сценария, приходится поддерживать все объекты в иерархии, причем оно еще и циклическое все наверняка.
А если новый сценарий появляется, что делаем?

ЛИ> В случае же, когда нас интересует только один аспект Работника, механизм lazy loading гарантирует нам, что "лишние" данные вообще не будут фигурировать в операции.

Так же она нам гарантирует массу побочных эффектов связаных с непредсказуемостью момента загрузки и гарантированный просад по производительности.
LL — это кривизна с обратным радиусом, для выправления кривизны под названием навигационный доступ.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[24]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 08:47
Оценка: 11 (2)
Здравствуйте, meowth, Вы писали:

M>а)Объектный кеш позволяет перераспределить запросы во времени и снять нагрузку с БД по выборке данных. Странно, что вы с этим спорите.

Ничего странного.
M>б)"декларативных способов описания связей объектов" -- вы не связи объектов таким образом описываете, а связи записей в БД, т.е. элементов множеств. Это разные вещи.
С точки зрения предметной области, и то и другое — всего лишь несущественные подробности реализации. Поскольку один хрен в основании пирамиды лежат таблицы СУБД, полезность любой промежуточной прослойки требует отдельного доказательства. Простейший пример — если есть сценарий, в котором нужно найти, к примеру, список категорий товаров, заказанных определённым покупателем за определённый период времени, то в SQL есть простой и однозначный способ описать эту задачу в терминах конкретных таблиц и связей. ORM-прослойка не даёт в этом плане ничего нового; наоборот — она требует наличия в кэше большого количества промежуточных объектов, которые, в общем-то, в исходную постановку задачи не входили.
Никого не интересует, что в объекте Order есть коллекция Items, каждая из которых связана с объектом Product, из которого торчит ссылка на Category. Почему? Да потому, что в контексте этой задачи никакого поведения у объектов нету.
M>ИМХО вы меня не поняли. Там была жалоба на то, что LL увеличивает количество обращений к БД до неприличного в случае коллекций. А я говорил, что правильно настроенный lazy load может вытягивать эту коллекцию batch-ем -- скажем, 30 айтемов за 3 раза, а кроме того -- брать ее из кеша.
Прекрасно. Вот в задаче выше, anemic model вообще не загрузит в сервер ни одного Order и ни одного OrderItem. Причём, что характерно, без резервирования в аппсервере мегабайт памяти под эти объекты. И без расходов трафика на поддержание когерентности реплик кэша между узлами фармы.
Странно, что вы с этим спорите.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 08:47
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>А если нужно (можно) кешировать только часть запроса?

Не очень понятно, что вы называете "часть запроса".
WF>У нас есть две сущности, рейс и аэропорт. Кешировать результат запроса рейс+аэропорт смысла нет, рейс часто меняется, не хочется иметь проблем с синхронизацией кешей и БД. А вот аэропорт, сущность словарная, кешируется очень хорошо — по отдельности от рейса.
Что такое "запрос рейс+аэропорт"? Можно пример SQL?

WF>Так это искусственная сущность и есть результат запроса (вернее, его часть). Нам нужно сгенерировать письмо с информацией по рейсу + аэропорт (какие именно данные потребуется мы не знаем — используются шаблоны). Выбираем из БД рейс с «ленивой» привязкой к аэропорту — и вуаля, в большинстве случаев выбираться будут только данные по рейсу. Что нам и нужно.

Непонятно. Имеем два запроса: 1 запрос на детали рейса, 1 запрос на детали аэропорта. Вот у этого второго запроса есть lifetime; который достаточно велик для того, чтобы он жил в кэше.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 08:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Не очень понятно, что вы называете "часть запроса".


Информацию о аэропорте. Это если делать выборку как написано ниже.

S>Что такое "запрос рейс+аэропорт"? Можно пример SQL?


Примерно так:
select * from SEGMENT S inner join AIRPORT A on S.DEP_AIRPORT = A.ID where S.ID = 100;


S>Непонятно. Имеем два запроса: 1 запрос на детали рейса, 1 запрос на детали аэропорта. Вот у этого второго запроса есть lifetime; который достаточно велик для того, чтобы он жил в кэше.


Да, именно так у нас (с участием LL+кеш) и есть. Два запроса, второй живёт в кеше. Второй запрос = выборка аэропорта по id, потому в данном случае «закешированный запрос» == «закешированный объект».
Re[27]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 09:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, meowth, Вы писали:


M>>Здравствуйте, gandjustas, Вы писали:


WF>>>>1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД? А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.


G>>>Такое работает только для справочных данных. Их вообще можно кешировать на клиенте.


M>>Может, я вас не понял, но тут имхо вы не правы. До тех пор, пока кеш для связанных сущностей (например, коллекции дочерних сущностей) не был сброшен, для навигации внутри бизнес-логики они выбираются из кеша, т.к. навигация к ним осуществляется по id, а identity map отрабатывает эти моменты.


G>Для этого никакой кеши не нужен. Достаточно один раз загрузить сущность со связанными (выполняется join) на запрос и потом ходить по связанным сущностям сколько влезет. При этом если кто-то другой в этот момент поменяет связанную колеекцию, то фантомов у вас не появится (оптимистичная блокировка против них бессильна).


Не, ты меня не понял ИМХО. Вот в одном методе бизнес логики (или сервиса в твоей интерпретации) ты виртуозным join подгрузил эти связанные сущности. (я уже молчу про то, что сервис в таком случае должен знать схему БД, чтобы стрелять joinами), Затем вышел из сервиса А, и зашел в другой (B), в котором понадобились те же связанные сущности. Как быть -- загружать из БД опять? Как это обойти без кеша?
Re[25]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 09:17
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, meowth, Вы писали:


S>С точки зрения предметной области, и то и другое — всего лишь несущественные подробности реализации. Поскольку один хрен в основании пирамиды лежат таблицы СУБД, полезность любой промежуточной прослойки требует отдельного доказательства.

Предметной области глубоко пофик на то, что там за таблицы.

S>Простейший пример — если есть сценарий, в котором нужно найти, к примеру, список категорий товаров, заказанных определённым покупателем за определённый период времени, то в SQL есть простой и однозначный способ описать эту задачу в терминах конкретных таблиц и связей. ORM-прослойка не даёт в этом плане ничего нового;

Продолжайте писать в терминах таблиц, я ж не принуждаю никого. Это вы пенитесь, что rich -- это плохо.

S>наоборот — она требует наличия в кэше большого количества промежуточных объектов, которые, в общем-то, в исходную постановку задачи не входили.

Если ваш аргумент заключается в том, что rich требует кеша -- можете сразу на него забить (на аргумент). Это все равно, что спорить, что автомобиль плох, потому что требует бензин для работы.

S>Никого не интересует, что в объекте Order есть коллекция Items, каждая из которых связана с объектом Product, из которого торчит ссылка на Category. Почему? Да потому, что в контексте этой задачи никакого поведения у объектов нету.

Вы придумали задачу, я думаю здесь спорить бессмысленно, потому что там есть только то, что вы хотите.

S>Прекрасно. Вот в задаче выше, anemic model вообще не загрузит в сервер ни одного Order и ни одного OrderItem. Причём, что характерно, без резервирования в аппсервере мегабайт памяти под эти объекты. И без расходов трафика на поддержание когерентности реплик кэша между узлами фармы.

Очень интересно, как оно будет с этими данными работать, если не загрузит их себе в память из БД.

Про реплицированный кеш я ничего не говорил пока, не путайте одно с другим.
Re[22]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 09:22
Оценка:
Здравствуйте, WFrag, Вы писали:


S>>Что такое "запрос рейс+аэропорт"? Можно пример SQL?


WF>Примерно так:

WF>
WF>select * from SEGMENT S inner join AIRPORT A on S.DEP_AIRPORT = A.ID where S.ID = 100;
WF>


S>>Непонятно. Имеем два запроса: 1 запрос на детали рейса, 1 запрос на детали аэропорта. Вот у этого второго запроса есть lifetime; который достаточно велик для того, чтобы он жил в кэше.


WF>Да, именно так у нас (с участием LL+кеш) и есть. Два запроса, второй живёт в кеше. Второй запрос = выборка аэропорта по id, потому в данном случае «закешированный запрос» == «закешированный объект».


Приведите пример юзкейса где понадобится именно такая выборка без дополнительных проекций.
Re[28]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 09:28
Оценка:
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, meowth, Вы писали:


M>>>Здравствуйте, gandjustas, Вы писали:


WF>>>>>1 обращение не всегда хорошо. Может оказаться, что одна часть выборки очень хорошо кешируется — зачем тогда её каждый раз выбирать запросом, лишний раз нагружать СУБД? А в случае LL достаточно навесить кеширование на связанную сущность — и она выберется лишь один раз, дальше будет так же по одной выборке.


G>>>>Такое работает только для справочных данных. Их вообще можно кешировать на клиенте.


M>>>Может, я вас не понял, но тут имхо вы не правы. До тех пор, пока кеш для связанных сущностей (например, коллекции дочерних сущностей) не был сброшен, для навигации внутри бизнес-логики они выбираются из кеша, т.к. навигация к ним осуществляется по id, а identity map отрабатывает эти моменты.


G>>Для этого никакой кеши не нужен. Достаточно один раз загрузить сущность со связанными (выполняется join) на запрос и потом ходить по связанным сущностям сколько влезет. При этом если кто-то другой в этот момент поменяет связанную колеекцию, то фантомов у вас не появится (оптимистичная блокировка против них бессильна).


M>Не, ты меня не понял ИМХО. Вот в одном методе бизнес логики (или сервиса в твоей интерпретации) ты виртуозным join подгрузил эти связанные сущности. (я уже молчу про то, что сервис в таком случае должен знать схему БД, чтобы стрелять joinами)

А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.

M>Затем вышел из сервиса А, и зашел в другой (B), в котором понадобились те же связанные сущности. Как быть -- загружать из БД опять? Как это обойти без кеша?

Если два сервиса пользуются одиними и теми же данными, то данные им передает вызывающий код.
Re[29]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 01.06.09 09:38
Оценка: :)
Здравствуйте, gandjustas, Вы писали:

G>А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.


В одном случае о схеме знает специальная инфраструктура, которая в любом случае о ней знает, в другом сервисы логики.

G>Если два сервиса пользуются одиними и теми же данными, то данные им передает вызывающий код.


Т.е. вызывающий код должен знать все данные которые понадобятся сервисам для их логики?
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[23]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 09:38
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Приведите пример юзкейса где понадобится именно такая выборка без дополнительных проекций.


Пример: генерация текста (текстов) сообщений. Заранее неизвестно, какие шаблоны будут использованы и, соответственно, какая точная проекция нужна.

Цикл такой:

1) Выборка рейса.
2) Обновление по некоторым правилам.
3) Узнаем шаблоны, которые нужно использовать для генерации текстового сообщения.
4) Генерируем сообщения, отправляем.
Re[26]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 09:42
Оценка:
Здравствуйте, WFrag, Вы писали:
WF>Вот ты сам несколькими постами выше утверждал, что себестоимость запроса сильно зависит от набора полей. Зачем выбирать +N полей, если их можно взять из местного кеша?
Можно.
WF> Да, можно было это делать явно. Загружаем «рейс», делаем запрос к кешу, выбираем «аэропорт», формируем текст сообщения по шпблону.
Ну, к примеру, оба запроса всегда проходят через кэш. Просто у одного из них стоит cahe duration более длинная, чем у другого.
WF>Но зачем, если проще просто объявить аэропорт связанной с рейсом сущностью, и пометить как «кешируемо»? А ORM всё сделает за нас.
Это не проще. Аэропорт никак не связан с рейсом. ORM будет делать за вас не то, что нужно.

WF>Не понял мысли. Предлагается вообще не хранить словарную сущность («аэропорт») в БД?

Предлагается не полагаться на наличие этой сущности в кэше. Понадобилась — попросил.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[29]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 09:43
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

M>>Не, ты меня не понял ИМХО. Вот в одном методе бизнес логики (или сервиса в твоей интерпретации) ты виртуозным join подгрузил эти связанные сущности. (я уже молчу про то, что сервис в таком случае должен знать схему БД, чтобы стрелять joinами)

G>А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.
Чтобы делать или не делать LL, код не нужно править. Можно отключить или включить LL в конфиге, причем для тех сущностей, которых надо. Ну и там же указать, подтягивать ли их отдельным запросом или join'ить (если это eager load). Ну и естессно, кеш работает в любом случае

M>>Затем вышел из сервиса А, и зашел в другой (B), в котором понадобились те же связанные сущности. Как быть -- загружать из БД опять? Как это обойти без кеша?

G>Если два сервиса пользуются одними и теми же данными, то данные им передает вызывающий код.
Как-то очень грустно получается: N сервисов связаны не только контрактом сущностей, с которыми они работают, но и общими данными с M клиентами, которые их вызывают. Причем вызывающий код должен точно знать до состава полей, какие данные понадобятся сервисам, чтобы не загрузить лишнего. А если сервис переписан и требует дополнительных полей, то придется переписать и всех его клиентов. При этом по контракту сервиса и непонятно, какие данные ему понадобятся, а какие нет -- скажем, если ему передается Order, надо ли грузить OrderItems.
Не, я понимаю, что такова идеология "чистый код + чистые данные раздельно" и по-другому никак, но, в общем, думаю, что это слабоватое место.
Re[30]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 09:47
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, gandjustas, Вы писали:


G>>А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.

Z>В одном случае о схеме знает специальная инфраструктура, которая в любом случае о ней знает, в другом сервисы логики.
Загрузкой данных всегда занимается специальная инфраструктура — различные ORM.

G>>Если два сервиса пользуются одиними и теми же данными, то данные им передает вызывающий код.

Z>Т.е. вызывающий код должен знать все данные которые понадобятся сервисам для их логики?
Естественно.
Re[24]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 09:53
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>Здравствуйте, gandjustas, Вы писали:


G>>Приведите пример юзкейса где понадобится именно такая выборка без дополнительных проекций.


WF>Пример: генерация текста (текстов) сообщений. Заранее неизвестно, какие шаблоны будут использованы и, соответственно, какая точная проекция нужна.


WF>Цикл такой:


WF>1) Выборка рейса.

WF>2) Обновление по некоторым правилам.
WF>3) Узнаем шаблоны, которые нужно использовать для генерации текстового сообщения.
WF>4) Генерируем сообщения, отправляем.

1-2 и 3-4 вроде как не связаны. В 3-4 вполне возможно строить динамически проекцию.
Re[31]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 01.06.09 09:53
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Загрузкой данных всегда занимается специальная инфраструктура — различные ORM.


Только в анемичной модели в DAL приходится хардкодить джойны.

Z>>Т.е. вызывающий код должен знать все данные которые понадобятся сервисам для их логики?

G>Естественно.

Хороший аргумент против ADM.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[26]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 09:59
Оценка: 1 (1)
Здравствуйте, meowth, Вы писали:

S>>Простейший пример — если есть сценарий, в котором нужно найти, к примеру, список категорий товаров, заказанных определённым покупателем за определённый период времени, то в SQL есть простой и однозначный способ описать эту задачу в терминах конкретных таблиц и связей. ORM-прослойка не даёт в этом плане ничего нового;

M>Продолжайте писать в терминах таблиц, я ж не принуждаю никого. Это вы пенитесь, что rich -- это плохо.
Я не пенюсь. Я пытаюсь объяснить очевидные вещи людям, спорящим с тривиальностиями.

M>Если ваш аргумент заключается в том, что rich требует кеша -- можете сразу на него забить (на аргумент). Это все равно, что спорить, что автомобиль плох, потому что требует бензин для работы.

Аналогия плоха. Но это неважно. Если вы хотите поговорить про кэш — пожалуйста, можем поговорить о недостатках кэша. Не хотите говорить о недостатках кэша — можем поговорить о неотъемлемых проблемах Rich model.

M>Вы придумали задачу, я думаю здесь спорить бессмысленно, потому что там есть только то, что вы хотите.

Конечно бессмысленно. Потому что в этой задаче анемик рвет вашу рич на тряпки. А теперь попробуйте придумать адекватный обратный пример. Окажется, что в лучшем случае рич будет играть 1:1 с анемик по объему кода, стоимости сопровождения, и эффективности реализации.

M>Очень интересно, как оно будет с этими данными работать, если не загрузит их себе в память из БД.

Интересно — поясняю: в запросе не были нужны эти данные. Перечитайте задачу еще раз. А, значит, и "работать" с ними не надо. И бояться, что кэш устарел, тоже не надо. И тратиться на обновление этого кэша — опять не надо. Ничего не надо. Всё, что надо — это список строк. И простая функция, которая отображает три параметра в список строк. Трафик между клиентом и сервером — минимален.
Эффективность — превосходная. Повторное исполнение этого запроса будет идти в памяти СУБД, потому что все нужные страницы Order/OrderItem подняты в его кэш в любом случае — независимо от анемичности модели в аппсервере. Тот кэш, про который вы говорите — это еще одна копия тех же данных. Зачем она вам?
M>Про реплицированный кеш я ничего не говорил пока, не путайте одно с другим.
А вам придется про него говорить, как только нагрузка вынудит вас перевести аппсервер на кластер. Никуда вы не денетесь. Опять же, из-за того, что больше работы делается в коде апп-сервера, вам придется это делать раньше, чем анемичной модели.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: Anemic Domain Model vs Rich Domain Model
От: Sinclair Россия https://github.com/evilguest/
Дата: 01.06.09 09:59
Оценка: 1 (1)
Здравствуйте, WFrag, Вы писали:

Правильный цикл:
1. Парсим шаблон, выясняем нужные данные
2. Строим набор запросов, вытаскивающих нужные данные
3. Прогоняем запросы через кэш.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[30]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 10:02
Оценка: +1
Здравствуйте, meowth, Вы писали:

M>Здравствуйте, gandjustas, Вы писали:


M>>>Не, ты меня не понял ИМХО. Вот в одном методе бизнес логики (или сервиса в твоей интерпретации) ты виртуозным join подгрузил эти связанные сущности. (я уже молчу про то, что сервис в таком случае должен знать схему БД, чтобы стрелять joinами)

G>>А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.
M>Чтобы делать или не делать LL, код не нужно править. Можно отключить или включить LL в конфиге, причем для тех сущностей, которых надо. Ну и там же указать, подтягивать ли их отдельным запросом или join'ить (если это eager load). Ну и естессно, кеш работает в любом случае
Без составления проекци толку нету.
Кстати как в таком случае запросы с аггрегацией работают?

M>>>Затем вышел из сервиса А, и зашел в другой (B), в котором понадобились те же связанные сущности. Как быть -- загружать из БД опять? Как это обойти без кеша?

G>>Если два сервиса пользуются одними и теми же данными, то данные им передает вызывающий код.
M>Как-то очень грустно получается: N сервисов связаны не только контрактом сущностей, с которыми они работают, но и общими данными с M клиентами, которые их вызывают. Причем вызывающий код должен точно знать до состава полей, какие данные понадобятся сервисам, чтобы не загрузить лишнего. А если сервис переписан и требует дополнительных полей, то придется переписать и всех его клиентов. При этом по контракту сервиса и непонятно, какие данные ему понадобятся, а какие нет -- скажем, если ему передается Order, надо ли грузить OrderItems.
Есть такая страная вещь как композиция. Например нужно какому либо сервсиу работать с деталями заказа, то ему передаются только детали заказа. Другому нужен order, то ему передается только он.
Кучка таких мелкийх сервисов собирается в более крупный, который соотвествует бизнес-транзакции типа "добавить айтем к ордеру". Соответственно внутри этого сервиса происходит все получение данных.

M>Не, я понимаю, что такова идеология "чистый код + чистые данные раздельно" и по-другому никак, но, в общем, думаю, что это слабоватое место.

Это смотря как писать. Функциональная композиция рулит.
А ЗД или другой код более высокого уровня образается только к сервисам которые отдают данные и не имеют побочных эффектов или передают запрос на изменение данных. (Command-Query Separation в чистом виде).
Re[25]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 10:08
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Правильный цикл:

S>1. Парсим шаблон, выясняем нужные данные
S>2. Строим набор запросов, вытаскивающих нужные данные
S>3. Прогоняем запросы через кэш.

Нет, так не выйдет. Мы не знаем шаблон(-ы), пока не обновим запись. В моём списке пункт 3 не зря идёт после 2. Более того, на этапе 2 мы тоже не особо знаем, какие данные нужны, т.к есть такая нехорошая точка расширения под названием «noise filter», которая может на основании любых фантазий о записи (включая историю изменений записи) отменить её изменение, но это (в теории) решаемо добавлением метода к фильтру, который бы выяснял, что ему надо.

И самое главное, не очень понятно, зачем это нужно. Очень похоже на premature optimization. По текущим тестам, сейчас тормозят совсем не эти запросы, тем более, что поля все идут из одной строки таблицы (а остальные поля идут из кеша словарных данных)
Re[32]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 10:11
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, gandjustas, Вы писали:


G>>Загрузкой данных всегда занимается специальная инфраструктура — различные ORM.

Z>Только в анемичной модели в DAL приходится хардкодить джойны.
Джоины хардкодятся просто нереально тяжко.
Вот был у меня запрос на вытаскиванпе ордера

var q = from o in _orders
        where o.Id == someId
        select o;


А тут мне понадобилось получать ордер вместе с айтемами. И я поменял почти полпрограммы чтобы получить такой эффект.

var q = from o in _orders.With(ord => ord.OrderItems)
        where o.Id == someId
        select o;



Z>>>Т.е. вызывающий код должен знать все данные которые понадобятся сервисам для их логики?

G>>Естественно.
Z>Хороший аргумент против ADM.
Вы не понимаетео чем говорите.
Re[25]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 10:17
Оценка:
Здравствуйте, gandjustas, Вы писали:

WF>>Пример: генерация текста (текстов) сообщений. Заранее неизвестно, какие шаблоны будут использованы и, соответственно, какая точная проекция нужна.


WF>>Цикл такой:


WF>>1) Выборка рейса.

WF>>2) Обновление по некоторым правилам.
WF>>3) Узнаем шаблоны, которые нужно использовать для генерации текстового сообщения.
WF>>4) Генерируем сообщения, отправляем.

G>1-2 и 3-4 вроде как не связаны. В 3-4 вполне возможно строить динамически проекцию.


Связаны, в том смысле, что только после обновления записи мы знаем какие шаблоны нам нужны (и нужны ли вообще). Грубо говоря, смысл такой, что каждое изменение в пункте 2 (их может быть несколько) генерирует событие (которое зависит от старого состояния), по которому мы ищем привязанные сообщения.

Например, если реальное время отрыва от полосы было NULL, а стало не NULL и старое состояние было CHECK_IN, то генерируется событие DEPARTED. К которому может быть привязано любое сообщение. Например, «Рейс ${segment.flightNumber} улетел из ${segment.depAirport.name} (${segment.depAirport.iata})».
Re[31]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 10:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, meowth, Вы писали:


M>>Здравствуйте, gandjustas, Вы писали:


M>>>>Не, ты меня не понял ИМХО. Вот в одном методе бизнес логики (или сервиса в твоей интерпретации) ты виртуозным join подгрузил эти связанные сущности. (я уже молчу про то, что сервис в таком случае должен знать схему БД, чтобы стрелять joinами)

G>>>А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.
M>>Чтобы делать или не делать LL, код не нужно править. Можно отключить или включить LL в конфиге, причем для тех сущностей, которых надо. Ну и там же указать, подтягивать ли их отдельным запросом или join'ить (если это eager load). Ну и естессно, кеш работает в любом случае
G>Без составления проекци толку нету.
Толку в чем?

G>Кстати как в таком случае запросы с аггрегацией работают?

Так же, как и раньше.

G>>>Если два сервиса пользуются одними и теми же данными, то данные им передает вызывающий код.

M>>Как-то очень грустно получается: N сервисов связаны не только контрактом сущностей, с которыми они работают, но и общими данными с M клиентами, которые их вызывают. Причем вызывающий код должен точно знать до состава полей, какие данные понадобятся сервисам, чтобы не загрузить лишнего. А если сервис переписан и требует дополнительных полей, то придется переписать и всех его клиентов. При этом по контракту сервиса и непонятно, какие данные ему понадобятся, а какие нет -- скажем, если ему передается Order, надо ли грузить OrderItems.
G>Есть такая страная вещь как композиция. Например нужно какому либо сервсиу работать с деталями заказа, то ему передаются только детали заказа. Другому нужен order, то ему передается только он.
G>Кучка таких мелкийх сервисов собирается в более крупный, который соотвествует бизнес-транзакции типа "добавить айтем к ордеру".
Вам счас не об этом говорят. Функциональную композицию никто не отменял, и фасадная организация a la transactional script -- это нормально. Говорят о том, что сервисы становятся хрупкими и еще код, который мог бы находиться в инфраструктуре, теперь надо пихать в сервис.
G>Соответственно внутри этого сервиса происходит все получение данных.
Понадобятся ли они на самом деле -- это вопрос, на который нельзя ответить.

M>>Не, я понимаю, что такова идеология "чистый код + чистые данные раздельно" и по-другому никак, но, в общем, думаю, что это слабоватое место.

G>Это смотря как писать. Функциональная композиция рулит.
Если писать "смотря как", то можно на любой модели сделать конфетку ФК тут не при чем.
G>А ЗД или другой код более высокого уровня образается только к сервисам которые отдают данные и не имеют побочных эффектов или передают запрос на изменение данных. (Command-Query Separation в чистом виде).
Чтобы они отдавали данные, им нужно знать, какие данные отдавать. Причем договориться еще с тучей сервисов, что приедут именно нужные данные.
Re[33]: Anemic Domain Model vs Rich Domain Model
От: Ziaw Россия  
Дата: 01.06.09 10:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А тут мне понадобилось получать ордер вместе с айтемами. И я поменял почти полпрограммы чтобы получить такой эффект.


G>
G>var q = from o in _orders.With(ord => ord.OrderItems)
G>


aggregation root detected, а сколько было на него вылито грязи?

G>Вы не понимаетео чем говорите.


по делу есть что сказать?
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[26]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 10:24
Оценка:
Здравствуйте, WFrag, Вы писали:

WF>Здравствуйте, gandjustas, Вы писали:


WF>>>Пример: генерация текста (текстов) сообщений. Заранее неизвестно, какие шаблоны будут использованы и, соответственно, какая точная проекция нужна.


WF>>>Цикл такой:


WF>>>1) Выборка рейса.

WF>>>2) Обновление по некоторым правилам.
WF>>>3) Узнаем шаблоны, которые нужно использовать для генерации текстового сообщения.
WF>>>4) Генерируем сообщения, отправляем.

G>>1-2 и 3-4 вроде как не связаны. В 3-4 вполне возможно строить динамически проекцию.


WF>Связаны, в том смысле, что только после обновления записи мы знаем какие шаблоны нам нужны (и нужны ли вообще). Грубо говоря, смысл такой, что каждое изменение в пункте 2 (их может быть несколько) генерирует событие (которое зависит от старого состояния), по которому мы ищем привязанные сообщения.


WF>Например, если реальное время отрыва от полосы было NULL, а стало не NULL и старое состояние было CHECK_IN, то генерируется событие DEPARTED. К которому может быть привязано любое сообщение. Например, «Рейс ${segment.flightNumber} улетел из ${segment.depAirport.name} (${segment.depAirport.iata})».


Все равно не пойму в каком юзкейсе такое всречается. А то у вас data-driven в прямом смысле приложение получается, сценарии работы зависят от изменения данных. (хотя реально наоборот происходит)
Re[34]: Anemic Domain Model vs Rich Domain Model
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.06.09 10:26
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Здравствуйте, gandjustas, Вы писали:


G>>А тут мне понадобилось получать ордер вместе с айтемами. И я поменял почти полпрограммы чтобы получить такой эффект.


G>>
G>>var q = from o in _orders.With(ord => ord.OrderItems)
G>>


Z>aggregation root detected, а сколько было на него вылито грязи?

какой aggregation root? Просто данные и связи между ними.
Или это уже симптомы человека с молотком?
Re[27]: Anemic Domain Model vs Rich Domain Model
От: WFrag США  
Дата: 01.06.09 10:31
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Все равно не пойму в каком юзкейсе такое всречается. А то у вас data-driven в прямом смысле приложение получается, сценарии работы зависят от изменения данных. (хотя реально наоборот происходит)


Юз-кейз: оповестить пользователя о интересующем его событии. Интересующее его событие засылается клиентом в виде запроса заранее. Далее прилетают обновления данных о рейсе, нужно отреагировать соответствующим образом.

Типа: «хочу знать, когда взлетит рейс SU 1337 из Тьмутаракани 1 июня 2009, после взлёта отправьте мне сообщение XXX на номер YYY».
Re[27]: Anemic Domain Model vs Rich Domain Model
От: meowth  
Дата: 01.06.09 10:32
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, meowth, Вы писали:


S>>>Простейший пример — если есть сценарий, в котором нужно найти, к примеру, список категорий товаров, заказанных определённым покупателем за определённый период времени, то в SQL есть простой и однозначный способ описать эту задачу в терминах конкретных таблиц и связей. ORM-прослойка не даёт в этом плане ничего нового;

M>>Продолжайте писать в терминах таблиц, я ж не принуждаю никого. Это вы пенитесь, что rich -- это плохо.
S>Я не пенюсь. Я пытаюсь объяснить очевидные вещи людям, спорящим с тривиальностиями.
Очевидная вещь состоит в том, что современные тулы позволяют устранить "фатальные" недостатки rich-модели, заодно и переместив тучу инфраструктурного кода в инфраструктуру собственно. То, что вы не приемлете способы, которыми это достигается -- это другой вопрос. Скажем, при постановке задачи "не использовать кеш" я тоже не пользовался бы ни rich, ни и LL.

M>>Если ваш аргумент заключается в том, что rich требует кеша -- можете сразу на него забить (на аргумент). Это все равно, что спорить, что автомобиль плох, потому что требует бензин для работы.

S>Аналогия плоха. Но это неважно. Если вы хотите поговорить про кэш — пожалуйста, можем поговорить о недостатках кэша. Не хотите говорить о недостатках кэша — можем поговорить о неотъемлемых проблемах Rich model.
Имхо я выше все сказал.

M>>Вы придумали задачу, я думаю здесь спорить бессмысленно, потому что там есть только то, что вы хотите.

S>Конечно бессмысленно. Потому что в этой задаче анемик рвет вашу рич на тряпки. А теперь попробуйте придумать адекватный обратный пример. Окажется, что в лучшем случае рич будет играть 1:1 с анемик по объему кода, стоимости сопровождения, и эффективности реализации.
Оценить по "по объему кода, стоимости сопровождения, и эффективности реализации" можно, только поимев этот эксперимент на практике, к сожалению. Но ничего -- там gandjustas обещал написать sample. Вероятно, лучше всего будет попробовать переписать его на rich и сравнить

M>>Очень интересно, как оно будет с этими данными работать, если не загрузит их себе в память из БД.

S>Интересно — поясняю: в запросе не были нужны эти данные. Перечитайте задачу еще раз. А, значит, и "работать" с ними не надо. И бояться, что кэш устарел, тоже не надо. И тратиться на обновление этого кэша — опять не надо. Ничего не надо. Всё, что надо — это список строк. И простая функция, которая отображает три параметра в список строк. Трафик между клиентом и сервером — минимален.
Если они не были нужны, то правильный LL их тоже не будет загружать.

S>Эффективность — превосходная. Повторное исполнение этого запроса будет идти в памяти СУБД, потому что все нужные страницы Order/OrderItem подняты в его кэш в любом случае — независимо от анемичности модели в аппсервере. Тот кэш, про который вы говорите — это еще одна копия тех же данных. Зачем она вам?

Поясняю -- этот кеш работает шустрее: "выборка из памяти БД" vs "выборка с включенным кешем" показывает, что из кеша приезжает в ~10-15 раз быстрее. При том, что из БД ведется только выборка, а из кеша едут уже объекты. Запрос простейший типа "select
  • from [table]". Кеш стоит на той же машине, что и БД. Я предполагаю, что вы скажете -- "у вас неправильно настроена БД", и опровергнуть это невозможно

    M>>Про реплицированный кеш я ничего не говорил пока, не путайте одно с другим.

    S>А вам придется про него говорить, как только нагрузка вынудит вас перевести аппсервер на кластер. Никуда вы не денетесь. Опять же, из-за того, что больше работы делается в коде апп-сервера, вам придется это делать раньше, чем анемичной модели.
    Сейчас кластер. Реплицированный кеш не используется -- используется DHT, который memcached.
  • Re[26]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 01.06.09 10:33
    Оценка:
    Здравствуйте, WFrag, Вы писали:
    WF>Нет, так не выйдет. Мы не знаем шаблон(-ы), пока не обновим запись.
    В таком случае читать что-либо до "обновления записи", что бы это ни значило, крайне противопоказано.

    WF>И самое главное, не очень понятно, зачем это нужно. Очень похоже на premature optimization. По текущим тестам, сейчас тормозят совсем не эти запросы, тем более, что поля все идут из одной строки таблицы (а остальные поля идут из кеша словарных данных)

    Cам по себе кэш словарных данных — плох потому, что он явно вводит лишнее понятие "словарные данные". Где у вас граница между словарными и несловарными данными? В нормальной системе имеет место целый континуум состояний — от expiration: now до expiration: never.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[32]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 10:33
    Оценка:
    Здравствуйте, meowth, Вы писали:

    M>Здравствуйте, gandjustas, Вы писали:


    G>>Здравствуйте, meowth, Вы писали:


    M>>>Здравствуйте, gandjustas, Вы писали:


    M>>>>>Не, ты меня не понял ИМХО. Вот в одном методе бизнес логики (или сервиса в твоей интерпретации) ты виртуозным join подгрузил эти связанные сущности. (я уже молчу про то, что сервис в таком случае должен знать схему БД, чтобы стрелять joinами)

    G>>>>А чтобы LL делать схему знать не надо? Причем не кому-либо, а самому объекту с данными. Вот тебе и связность.
    M>>>Чтобы делать или не делать LL, код не нужно править. Можно отключить или включить LL в конфиге, причем для тех сущностей, которых надо. Ну и там же указать, подтягивать ли их отдельным запросом или join'ить (если это eager load). Ну и естессно, кеш работает в любом случае
    G>>Без составления проекци толку нету.
    M>Толку в чем?
    В eager-load даже с кешем.

    G>>Кстати как в таком случае запросы с аггрегацией работают?

    M>Так же, как и раньше.
    Никак?

    G>>>>Если два сервиса пользуются одними и теми же данными, то данные им передает вызывающий код.

    M>>>Как-то очень грустно получается: N сервисов связаны не только контрактом сущностей, с которыми они работают, но и общими данными с M клиентами, которые их вызывают. Причем вызывающий код должен точно знать до состава полей, какие данные понадобятся сервисам, чтобы не загрузить лишнего. А если сервис переписан и требует дополнительных полей, то придется переписать и всех его клиентов. При этом по контракту сервиса и непонятно, какие данные ему понадобятся, а какие нет -- скажем, если ему передается Order, надо ли грузить OrderItems.
    G>>Есть такая страная вещь как композиция. Например нужно какому либо сервсиу работать с деталями заказа, то ему передаются только детали заказа. Другому нужен order, то ему передается только он.
    G>>Кучка таких мелкийх сервисов собирается в более крупный, который соотвествует бизнес-транзакции типа "добавить айтем к ордеру".
    M>Вам счас не об этом говорят. Функциональную композицию никто не отменял, и фасадная организация a la transactional script -- это нормально. Говорят о том, что сервисы становятся хрупкими и еще код, который мог бы находиться в инфраструктуре, теперь надо пихать в сервис.
    G>>Соответственно внутри этого сервиса происходит все получение данных.
    M>Понадобятся ли они на самом деле -- это вопрос, на который нельзя ответить.
    Это как раз вопрос, на который нужно отвечать.
    Любая бизнес-транзакция направлена на изменение определенного набора данных.

    M>>>Не, я понимаю, что такова идеология "чистый код + чистые данные раздельно" и по-другому никак, но, в общем, думаю, что это слабоватое место.

    G>>Это смотря как писать. Функциональная композиция рулит.
    M>Если писать "смотря как", то можно на любой модели сделать конфетку ФК тут не при чем.
    G>>А ЗД или другой код более высокого уровня образается только к сервисам которые отдают данные и не имеют побочных эффектов или передают запрос на изменение данных. (Command-Query Separation в чистом виде).
    M>Чтобы они отдавали данные, им нужно знать, какие данные отдавать. Причем договориться еще с тучей сервисов, что приедут именно нужные данные.
    Естественно. А все эти сервисы — маленькие и их лекго тестировать и повторно использовать.
    Re[35]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 10:37
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>какой aggregation root? Просто данные и связи между ними.

    G>Или это уже симптомы человека с молотком?

    Дай свое определение aggregation root. Под которое не попадет Order.OrderItems.


    Я вижу один большой минус в таком коде — мы должны точно знать до полей какие данные понадобятся нам в данной транзакции. И четко отслеживать изменение их состава при изменении кода. Тесты тут помогут слабо, ибо данные == dafault(T) могут означать как реальные данные поднятые из БД на которых должен работать сценарий так и данные которые просто забыли поднять.

    Тестировать, что поднимаются нужные и только нужные данные означает тупо дублировать логику поднятия, надеясь, что в двух местах совершить одну и ту же ошибку будет сложнее.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[28]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 10:46
    Оценка:
    Здравствуйте, WFrag, Вы писали:

    WF>Здравствуйте, gandjustas, Вы писали:


    G>>Все равно не пойму в каком юзкейсе такое всречается. А то у вас data-driven в прямом смысле приложение получается, сценарии работы зависят от изменения данных. (хотя реально наоборот происходит)


    WF>Юз-кейз: оповестить пользователя о интересующем его событии. Интересующее его событие засылается клиентом в виде запроса заранее. Далее прилетают обновления данных о рейсе, нужно отреагировать соответствующим образом.


    WF>Типа: «хочу знать, когда взлетит рейс SU 1337 из Тьмутаракани 1 июня 2009, после взлёта отправьте мне сообщение XXX на номер YYY».


    Ну как я себе это представляю:
    1)В системе есть какой-то внешний вход, который говорит что произошло событие типа X с параметрами y,z.
    2)Есть можество подписок на разные события.
    3)При наступлении события получаем все сообщения подисок, которые соотвествуют этим событиям.
    4)Определяем запрос, соотвествующий этому событию.
    5)Парсим все сообщения, получаем список необходимых полей.
    6)Накладываем нужную проекцию на запрос.
    7)Вполняем запрос, получает результаты в структуре типа словаря и генерирем нужные тексты.
    Re[27]: Anemic Domain Model vs Rich Domain Model
    От: WFrag США  
    Дата: 01.06.09 10:47
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>В таком случае читать что-либо до "обновления записи", что бы это ни значило, крайне противопоказано.


    Обновление записи — это не просто SQL-ный update. Нужно посмотреть предыдущие значения аттрибутов (и запомнить их), обновить их (прогнав каждое изменение через «noise» фильтр, обладающий правом «вето») и состояние рейса (если изменилось), получить список произошедших изменений.

    S>Cам по себе кэш словарных данных — плох потому, что он явно вводит лишнее понятие "словарные данные". Где у вас граница между словарными и несловарными данными? В нормальной системе имеет место целый континуум состояний — от expiration: now до expiration: never.


    Это условное понятие. Понятно, что кешировать можно всё, что захочется. Но так как нам не хочется возиться с когерентностью кешей и кластерными блокировками (тем более, что СУБД действительно лучше с этим справится), то там, где мы можем позволить временное нарушение консистентности (пока инвалидация пройдёт по узлам) — мы используем кеш (с любым expiration-ом, какой нам нужен), там где нет — увы.
    Re[28]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 01.06.09 10:50
    Оценка:
    Здравствуйте, meowth, Вы писали:

    M>Очевидная вещь состоит в том, что современные тулы позволяют устранить "фатальные" недостатки rich-модели, заодно и переместив тучу инфраструктурного кода в инфраструктуру собственно. То, что вы не приемлете способы, которыми это достигается -- это другой вопрос. Скажем, при постановке задачи "не использовать кеш" я тоже не пользовался бы ни rich, ни и LL.

    Я не понимаю, куда денутся фатальные недостатки рич-модели вроде высокой связности и плохой предсказуемости взаимодействия с СУБД. Если тщательно следить за выполнением гигиены, то получим ту же анемичную модель.

    M>Оценить по "по объему кода, стоимости сопровождения, и эффективности реализации" можно, только поимев этот эксперимент на практике, к сожалению. Но ничего -- там gandjustas обещал написать sample. Вероятно, лучше всего будет попробовать переписать его на rich и сравнить

    Ок.

    M>Если они не были нужны, то правильный LL их тоже не будет загружать.

    LL, по определению, будет срабатывать в момент обращения. Да, я в курсе, что некоторые толстые ORM позволяют написать "запрос" и выполнить его без подъема промежуточных данных в кэш. Ну, разве что как правило будут подняты полные экземпляры класса Category вместо отдельных строк, но это на фоне остального ужаса — семечки.
    Но в таком случае мы имеем опять же анемичную модель вид сбоку, и совершенно непонятно, ради чего вообще было городить какие-то классы ордеров с каким-то поведением.
    Ну и, конечно же, чтобы получить такой случай, нужно не забывать бить по пальцам ОО-девелоперов, которые будут насиловать LL выполнением этого запроса в императивном виде:
    foreach(var o in customer.Orders)
    {
      if (o.Date > startDate && o.Date < endDate)
        {
          foreach(var i in o.Items)
            {
              if (!categories.Contains(i.Product.Category.Name))
                {
                  categories.Add(i.Product.Category.Name
                }
            }
        }
    }

    Вот эту штуку очень легко написать; rich model и LL даже обеспечат ее работоспособность, но система в целом — ляжет. По причинам, очевидным для всех "анемистов".

    M>Поясняю -- этот кеш работает шустрее: "выборка из памяти БД" vs "выборка с включенным кешем" показывает, что из кеша приезжает в ~10-15 раз быстрее. При том, что из БД ведется только выборка, а из кеша едут уже объекты. Запрос простейший типа "select
  • from [table]". Кеш стоит на той же машине, что и БД. Я предполагаю, что вы скажете -- "у вас неправильно настроена БД", и опровергнуть это невозможно
    Я скажу: вы исполняете синтетический запрос.
    В жизни "select *" не нужен практически никогда. Как только вы начнёте оперировать настоящими запросами, которые потребуются в бизнес логике, статистика резко изменится в пользу СУБД. Вы легко отличите настоящие запросы от искусственных:
    1. В настоящих запросах всегда стоит непустой where
    2. В них всегда написан конкретный список полей перед from
    Во многих случаях в запросе потребуются join. В некоторых также будут применены агрегаты и group by.

    M>Сейчас кластер. Реплицированный кеш не используется -- используется DHT, который memcached.

    Тогда расскажите мне, каким образом обеспечивается когерентность кэша. Может, я не понимаю чего-то очевидного?
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
  • Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[29]: Anemic Domain Model vs Rich Domain Model
    От: WFrag США  
    Дата: 01.06.09 10:54
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    WF>>Типа: «хочу знать, когда взлетит рейс SU 1337 из Тьмутаракани 1 июня 2009, после взлёта отправьте мне сообщение XXX на номер YYY».


    G>Ну как я себе это представляю:

    G>1)В системе есть какой-то внешний вход, который говорит что произошло событие типа X с параметрами y,z.

    Не совсем. События, по которым определяется список сообщений для отправки, генерирует именно наша система, обновляя ровно ту же запись, что используется в сообщениях, на основании данных нескольких внешних систем (которые, вообще говоря, могут выдавать даже противоречивые данные).

    G>2)Есть можество подписок на разные события.

    G>3)При наступлении события получаем все сообщения подисок, которые соотвествуют этим событиям.
    G>4)Определяем запрос, соотвествующий этому событию.
    G>5)Парсим все сообщения, получаем список необходимых полей.
    G>6)Накладываем нужную проекцию на запрос.
    G>7)Вполняем запрос, получает результаты в структуре типа словаря и генерирем нужные тексты.

    В остальном всё примерно так.

    Вообще, если напрячься, то можно протащить всю информацию о требуемых поля до самого начала. Непонятно только, зачем? Система усложнится довольно существенно (нужно извлекать зависимости из шаблонов, noise filter-ов (которые будут писаться вообще отдельно, а значит мы не можем гарантировать их качество), пришедших событий как таковых. А выгода мне совершенно не очевидна. Я смотрю slow queries log и вижу, что тормозят-то другие запросы.
    Re[36]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 11:01
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>какой aggregation root? Просто данные и связи между ними.

    G>>Или это уже симптомы человека с молотком?

    Z>Дай свое определение aggregation root. Под которое не попадет Order.OrderItems

    Придерживаюсь такого http://domaindrivendesign.org/node/88.
    Order.OrderItems не для data changes, и никаких "consistency rules" у него нету.
    Кроме того OrderItem.Order такое же право на существование имеет.
    Вообще говоря я такую запись воспринимаю как SQL-ный JOIN по ключам, только гораздо короче.

    Z>Я вижу один большой минус в таком коде — мы должны точно знать до полей какие данные понадобятся нам в данной транзакции. И четко отслеживать изменение их состава при изменении кода.

    Это не минус. При работе с данными всетаки необходимо иметь представление о том что вытягивается из базы.

    Z>Тесты тут помогут слабо, ибо данные == dafault(T) могут означать как реальные данные поднятые из БД на которых должен работать сценарий так и данные которые просто забыли поднять.

    Это не так. default(T) в случае связанных данных это null. Интеграционные тесты отлавливают такое на ура.
    Для произвольных проекций создаются анонимные или реальные объекты, если их потом нужно куда-либо передавать.

    Z>Тестировать, что поднимаются нужные и только нужные данные означает тупо дублировать логику поднятия, надеясь, что в двух местах совершить одну и ту же ошибку будет сложнее.

    Это обеспечивается инфраструктурой и типами. В том случае где не обеспечивается — помогает интеграционное тестирование.
    Re[29]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 11:06
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>Я не понимаю, куда денутся фатальные недостатки рич-модели вроде высокой связности и плохой предсказуемости взаимодействия с СУБД. Если тщательно следить за выполнением гигиены, то получим ту же анемичную модель.


    Запросы предсказываются не сложнее чем сиквельный результат линка.

    M>>Оценить по "по объему кода, стоимости сопровождения, и эффективности реализации" можно, только поимев этот эксперимент на практике, к сожалению. Но ничего -- там gandjustas обещал написать sample. Вероятно, лучше всего будет попробовать переписать его на rich и сравнить

    S>Ок.

    S>Но в таком случае мы имеем опять же анемичную модель вид сбоку, и совершенно непонятно, ради чего вообще было городить какие-то классы ордеров с каким-то поведением.

    S>Ну и, конечно же, чтобы получить такой случай, нужно не забывать бить по пальцам ОО-девелоперов, которые будут насиловать LL выполнением этого запроса в императивном виде:
    S>
    S>foreach(var o in customer.Orders)
    S>{
    S>  if (o.Date > startDate && o.Date < endDate)
    S>    {
    S>      foreach(var i in o.Items)
    S>        {
    S>          if (!categories.Contains(i.Product.Category.Name))
    S>            {
    S>              categories.Add(i.Product.Category.Name
    S>            }
    S>        }
    S>    }
    S>} 
    S>

    S>Вот эту штуку очень легко написать; rich model и LL даже обеспечат ее работоспособность, но система в целом — ляжет. По причинам, очевидным для всех "анемистов".

    Такому разработчику никто не запретит написать перед этим в анемичной модели от ганжустаса
    Автор: gandjustas
    Дата: 01.06.09
    код подобный
    var q = from o in _orders.With(ord => ord.OrderItems).With(item => item.Product).With(product => product.Category)
            where o.Id == someId
            select o;

    Т.е. для подобных разработчиков обе модели дают одинаковые возможности для укладывания сервера.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[29]: Anemic Domain Model vs Rich Domain Model
    От: meowth  
    Дата: 01.06.09 11:18
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    M>>Очевидная вещь состоит в том, что современные тулы позволяют устранить "фатальные" недостатки rich-модели, заодно и переместив тучу инфраструктурного кода в инфраструктуру собственно. То, что вы не приемлете способы, которыми это достигается -- это другой вопрос. Скажем, при постановке задачи "не использовать кеш" я тоже не пользовался бы ни rich, ни и LL.

    S>Я не понимаю, куда денутся фатальные недостатки рич-модели вроде высокой связности и плохой предсказуемости взаимодействия с СУБД. Если тщательно следить за выполнением гигиены, то получим ту же анемичную модель.
    Я не вижу этих фатальных недостатков, и, видимо, не пойму никогда.

    M>>Оценить по "по объему кода, стоимости сопровождения, и эффективности реализации" можно, только поимев этот эксперимент на практике, к сожалению. Но ничего -- там gandjustas обещал написать sample. Вероятно, лучше всего будет попробовать переписать его на rich и сравнить

    S>Ок.

    M>>Если они не были нужны, то правильный LL их тоже не будет загружать.

    S>LL, по определению, будет срабатывать в момент обращения.
    Никто не спорит. Но подтягивать он будет или по одному, или пачками.

    S>Да, я в курсе, что некоторые толстые ORM позволяют написать "запрос" и выполнить его без подъема промежуточных данных в кэш. Ну, разве что как правило будут подняты полные экземпляры класса Category вместо отдельных строк, но это на фоне остального ужаса — семечки.

    Я этот вопрос и не затрагивал. Не надо создавать негативное ощущение перечислением недостатков, не относящихся к проблеме. Как правило -- видимо, с какого-то момента стало "как исключение".

    S>Ну и, конечно же, чтобы получить такой случай, нужно не забывать бить по пальцам ОО-девелоперов, которые будут насиловать LL выполнением этого запроса в императивном виде:

    S>
    S>foreach(var o in customer.Orders)
    S>{
    S>  if (o.Date > startDate && o.Date < endDate)
    S>    {
    S>      foreach(var i in o.Items)
    S>        {
    S>          if (!categories.Contains(i.Product.Category.Name))
    S>            {
    S>              categories.Add(i.Product.Category.Name
    S>            }
    S>        }
    S>    }
    S>} 
    S>

    S>Вот эту штуку очень легко написать; rich model и LL даже обеспечат ее работоспособность, но система в целом — ляжет. По причинам, очевидным для всех "анемистов".
    Мне не понятно, почему такое ляжет. Batch load вытянет вам все, что надо, в несколько запросов. Настройте так, чтобы их не было слишком много. В следующий раз коду, которому они понадобятся, все приедет из кеша.

    S>Я скажу: вы исполняете синтетический запрос.

    S>В жизни "select *" не нужен практически никогда. Как только вы начнёте оперировать настоящими запросами, которые потребуются в бизнес логике, статистика резко изменится в пользу СУБД. Вы легко отличите настоящие запросы от искусственных:
    S>1. В настоящих запросах всегда стоит непустой where
    S>2. В них всегда написан конкретный список полей перед from
    S>Во многих случаях в запросе потребуются join. В некоторых также будут применены агрегаты и group by.
    Ну вы же не думаете, наверное, что я исполнял именно select * from? Простейший -- в смысле, исключительно select. Использовались реальные запросы. При выборке по id запросы просто не доходят до БД, оставаясь в кеше. При сложных запросах кешируется их результат. Cached query все равно быстрее оказывается.

    M>>Сейчас кластер. Реплицированный кеш не используется -- используется DHT, который memcached.

    S>Тогда расскажите мне, каким образом обеспечивается когерентность кэша. Может, я не понимаю чего-то очевидного?
    Может быть. Что здесь неочевидного -- Вы не знаете, как организован DHT, который лочит области? Простите, я не будут тут это излагать.
    Re[30]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 11:18
    Оценка:
    Здравствуйте, WFrag, Вы писали:

    WF>Здравствуйте, gandjustas, Вы писали:


    WF>>>Типа: «хочу знать, когда взлетит рейс SU 1337 из Тьмутаракани 1 июня 2009, после взлёта отправьте мне сообщение XXX на номер YYY».


    G>>Ну как я себе это представляю:

    G>>1)В системе есть какой-то внешний вход, который говорит что произошло событие типа X с параметрами y,z.

    WF>Не совсем. События, по которым определяется список сообщений для отправки, генерирует именно наша система, обновляя ровно ту же запись, что используется в сообщениях, на основании данных нескольких внешних систем (которые, вообще говоря, могут выдавать даже противоречивые данные).

    Ниче не понял.
    Если у вас события отделены от состояния (например рейса), то все ок.
    Если нет — то это нарушение SRP.

    G>>2)Есть можество подписок на разные события.

    G>>3)При наступлении события получаем все сообщения подисок, которые соотвествуют этим событиям.
    G>>4)Определяем запрос, соотвествующий этому событию.
    G>>5)Парсим все сообщения, получаем список необходимых полей.
    G>>6)Накладываем нужную проекцию на запрос.
    G>>7)Вполняем запрос, получает результаты в структуре типа словаря и генерирем нужные тексты.

    WF>В остальном всё примерно так.


    WF>Вообще, если напрячься, то можно протащить всю информацию о требуемых поля до самого начала. Непонятно только, зачем? Система усложнится довольно существенно (нужно извлекать зависимости из шаблонов, noise filter-ов (которые будут писаться вообще отдельно, а значит мы не можем гарантировать их качество), пришедших событий как таковых. А выгода мне совершенно не очевидна.

    Это не нужно.

    Возвращаясь к исходному вопросу про кешированые связанных данных.
    При самом изменении состояния рейса может и не понадобиться данных об аэропорте. (в идеале такое должно выполняться одним запросом к БД на изменение).
    При динамическом составлении проекции тоже кешированные данные не помогут.
    Re[30]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 01.06.09 11:24
    Оценка:
    Здравствуйте, Ziaw, Вы писали:
    Z>Т.е. для подобных разработчиков обе модели дают одинаковые возможности для укладывания сервера.
    Неправда.
    Во-первых, нифига не одинаковые. Приведенный запрос быстро поднимет в память много объектов. Оригинал с LL будет выполнять миллионы мелких запросов в цикле.
    Во-вторых, разработчик — ленив. Он пишет локальный минимум того, что может.
    Поэтому в линке всё-таки будет
    var q = from o in _orders
                    from i in o.Items
            where o.Date > startDate && o.Date < endDate && o.CustomerId = customerId
            select i.Product.Name;

    Зачем он будет вставлять код, которым не пользуется?
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[37]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 11:26
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Придерживаюсь такого http://domaindrivendesign.org/node/88.

    G>Order.OrderItems не для data changes, и никаких "consistency rules" у него нету.
    G>Кроме того OrderItem.Order такое же право на существование имеет.
    G>Вообще говоря я такую запись воспринимаю как SQL-ный JOIN по ключам, только гораздо короче.

    Воспринимай ее также в рич модели, если тебе не нужен этот паттерн, зачем его применять?

    Z>>Я вижу один большой минус в таком коде — мы должны точно знать до полей какие данные понадобятся нам в данной транзакции. И четко отслеживать изменение их состава при изменении кода.

    G>Это не минус. При работе с данными всетаки необходимо иметь представление о том что вытягивается из базы.

    Миф о том, что в рич модели программист не имеет представления о вытягиваемых данных преувеличен.

    G>Это не так. default(T) в случае связанных данных это null. Интеграционные тесты отлавливают такое на ура.


    Я говорю о связях 0..1, т.е. null вполне адекватное представление данных, а у тебя он является еще и флагом !IsLoaded.

    G>Для произвольных проекций создаются анонимные или реальные объекты, если их потом нужно куда-либо передавать.


    Как и в рич модели

    G>Это обеспечивается инфраструктурой и типами. В том случае где не обеспечивается — помогает интеграционное тестирование.


    Не понял, как выглядит тест на то, что все нужные данные для транзакции поднимаются.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[31]: Anemic Domain Model vs Rich Domain Model
    От: WFrag США  
    Дата: 01.06.09 11:35
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    WF>>Не совсем. События, по которым определяется список сообщений для отправки, генерирует именно наша система, обновляя ровно ту же запись, что используется в сообщениях, на основании данных нескольких внешних систем (которые, вообще говоря, могут выдавать даже противоречивые данные).

    G>Ниче не понял.
    G>Если у вас события отделены от состояния (например рейса), то все ок.
    G>Если нет — то это нарушение SRP.

    Схема такая: Пришло N событий => на их основании обновляем рейс => получаем M новых событий => уже по этим событиям определяем сообщения => для каждого полученного события по рейсу (+связанные сущности типа аэропорт, перевозчик) и событию (которое содержит старое и новое значение) генерируем сообщение по шаблону.

    Чтобы на втором шаге обновить рейс нам просто необходимо его загрузить. Потому что обновление — это не просто update аттрибутов. Это информация типа «такой-то источник считает, что время отрыва от полосы — вот такое». Надо загрузить рейс, проанализировать его, и действовать соответственно. Можно проигнорировать обновление («noise filter» сработал), можно просто установить/обновить аттрибут, можно установить аттрибут и поменять состояние.

    Можно, конечно, на первом этапе грузить те аттрибуты, которые пришли в исходных событиях + ещё пара аттрибутов, а на втором ещё раз грузить рейс, но уже с теми аттрибутами, которые нужны для генерации сообщения. Но это уже два запроса.

    G>Возвращаясь к исходному вопросу про кешированые связанных данных.

    G>При самом изменении состояния рейса может и не понадобиться данных об аэропорте. (в идеале такое должно выполняться одним запросом к БД на изменение).

    Да, так и есть. Одним запросом и обновляется.

    G>При динамическом составлении проекции тоже кешированные данные не помогут.


    Так речь-то о том, что как составлять проекцию и при этом делать это простым способом — мне совершенно не очевидно. Даже просто парсить шаблон и осознавать, какие колонки нам нужны — это уже добавит сложности.
    Re[30]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 11:39
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    S>>Но в таком случае мы имеем опять же анемичную модель вид сбоку, и совершенно непонятно, ради чего вообще было городить какие-то классы ордеров с каким-то поведением.

    S>>Ну и, конечно же, чтобы получить такой случай, нужно не забывать бить по пальцам ОО-девелоперов, которые будут насиловать LL выполнением этого запроса в императивном виде:
    S>>
    S>>foreach(var o in customer.Orders)
    S>>{
    S>>  if (o.Date > startDate && o.Date < endDate)
    S>>    {
    S>>      foreach(var i in o.Items)
    S>>        {
    S>>          if (!categories.Contains(i.Product.Category.Name))
    S>>            {
    S>>              categories.Add(i.Product.Category.Name
    S>>            }
    S>>        }
    S>>    }
    S>>} 
    S>>

    S>>Вот эту штуку очень легко написать; rich model и LL даже обеспечат ее работоспособность, но система в целом — ляжет. По причинам, очевидным для всех "анемистов".

    Ну тут ты совсем мимо кассы.
    Считаем обращения к связанным данным в примере синклера.
    Поднять кастомера — 1
    customer.Orders — вытягивание всех ордеров — 1, предположим что в условие o.Date > startDate && o.Date < endDate попадает n штук.
    o.Items — вытягивание всех айтемом — 1*n
    i.Product.Category.Name — два запроса (один для Product, один для Category), в двух строчках такой кайф встречается.
    Итого 1+1+n+4n = 5n+2 запросов. Соотвественно это приведет к поднятию в кеш хотябы один раз множества объектов Product и Category.

    В Linq такой запрос бдет выглядеть так:

    (from o in Orders
    where Order.Customer.Id = custId //в SQL даже не будет ображения к таблице кастомеров
    where o.Date > startDate 
    where o.Date < endDate
    from item in o.Items
    select item.Product.Category.Name
    ).Distinct()

    При наличии индексов по дате ордера, ордеры не попадающие в диапазон дат даже не будут пондняты с диска. А продукты и категории будут считаны ровно один раз.

    Ну и кроме всего прочего это будет один запрос, а не 5n+2.

    Z>Такому разработчику никто не запретит написать перед этим в анемичной модели от ганжустаса
    Автор: gandjustas
    Дата: 01.06.09
    код подобный

    Z>
    Z>var q = from o in _orders.With(ord => ord.OrderItems).With(item => item.Product).With(product => product.Category)
    Z>        where o.Id == someId
    Z>        select o;
    
    Z>

    Z>Т.е. для подобных разработчиков обе модели дают одинаковые возможности для укладывания сервера.

    Во-первых код будет такой:
    var q = from o in _orders.With(ord => ord.OrderItems).With("OrderItems.Product.Category")
            where o.Id == someId
            select o;

    Во-вторых сразу видно что танется из базы и можно вполне резонно задавать вопросы зачем это тянется.
    В-третьих — даже такой запрос выполнится быстрее (причем гораздо быстрее), чем 5n+2 из примера синклера.
    Re[31]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 11:43
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>Во-первых, нифига не одинаковые. Приведенный запрос быстро поднимет в память много объектов. Оригинал с LL будет выполнять миллионы мелких запросов в цикле.


    Но поднимет он их, вероятно, на порядок больше чем требуется. А в рич модели тупой код будет примерно таким:
    foreach(Order o in s.Filter(customer.Orders, "where Date between ? and ?", new[] {startDate, endDate}) // 1 запрос
    {
        foreach(String name in 
            s.Filter(o.Items, "select Product.Category.Name where Product.Category in (?)", new[] {categories}) // +N запросов
        {
            categories.Add(name);
        }
    }

    Дальнейшая оптимизация нужна только если N ожидатеся реально большим.

    S>Во-вторых, разработчик — ленив. Он пишет локальный минимум того, что может.

    S>Поэтому в линке всё-таки будет
    S>
    S>var q = from o in _orders
    S>                from i in o.Items
    S>        where o.Date > startDate && o.Date < endDate && o.CustomerId = customerId
    S>        select i.Product.Name;
    S>

    S>Зачем он будет вставлять код, которым не пользуется?

    Именно потому, что он ленив, он не будет переделывать контракт метода с foreach в который передавался кастомер. Или всетаки такие методы сами выбирают нужные для себя данные?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[31]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 11:47
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Ну тут ты совсем мимо кассы.

    G>Считаем обращения к связанным данным в примере синклера.

    Пример синклера в рич модели выглядит обычно так
    Автор: Ziaw
    Дата: 01.06.09
    :

    G>В Linq такой запрос бдет выглядеть так:


    Такой запрос пишется в жирной модели точно также и транслируется в тот же сиквел.

    G>Во-вторых сразу видно что танется из базы и можно вполне резонно задавать вопросы зачем это тянется.


    Обращение к данным в рич модели тоже видно невооруженным глазом.

    G>В-третьих — даже такой запрос выполнится быстрее (причем гораздо быстрее), чем 5n+2 из примера синклера.


    1+N на самом деле.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[38]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 11:47
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Придерживаюсь такого http://domaindrivendesign.org/node/88.

    G>>Order.OrderItems не для data changes, и никаких "consistency rules" у него нету.
    G>>Кроме того OrderItem.Order такое же право на существование имеет.
    G>>Вообще говоря я такую запись воспринимаю как SQL-ный JOIN по ключам, только гораздо короче.

    Z>Воспринимай ее также в рич модели, если тебе не нужен этот паттерн, зачем его применять?

    В rich так не получится, там реальные объекты и кучи запросов.

    Z>>>Я вижу один большой минус в таком коде — мы должны точно знать до полей какие данные понадобятся нам в данной транзакции. И четко отслеживать изменение их состава при изменении кода.

    G>>Это не минус. При работе с данными всетаки необходимо иметь представление о том что вытягивается из базы.
    Z>Миф о том, что в рич модели программист не имеет представления о вытягиваемых данных преувеличен.
    ну-ну.

    G>>Это не так. default(T) в случае связанных данных это null. Интеграционные тесты отлавливают такое на ура.

    Z>Я говорю о связях 0..1, т.е. null вполне адекватное представление данных, а у тебя он является еще и флагом !IsLoaded.
    Ну вообще говоря и это неверно. EF напрмиер выдает вполне корректный exception если не загружена связь.

    G>>Для произвольных проекций создаются анонимные или реальные объекты, если их потом нужно куда-либо передавать.

    Z>Как и в рич модели
    Только это получается не rich
    Создавая везде кастомны еобъекты для представления результатов выоборок толку от domain objects и логики в них не остается.
    Поэтому хорошее rich приложение на самом деле примерно а 95% anemic.

    G>>Это обеспечивается инфраструктурой и типами. В том случае где не обеспечивается — помогает интеграционное тестирование.

    Z>Не понял, как выглядит тест на то, что все нужные данные для транзакции поднимаются.
    Так что не попадает null куда не надо.
    Re[39]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 11:56
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    Z>>Воспринимай ее также в рич модели, если тебе не нужен этот паттерн, зачем его применять?

    G>В rich так не получится, там реальные объекты и кучи запросов.

    В рич легко выполнять те же самые запросы, что и в анемик. Нет никаких препятствий для этого.

    G>Только это получается не rich

    G>Создавая везде кастомны еобъекты для представления результатов выоборок толку от domain objects и логики в них не остается.
    G>Поэтому хорошее rich приложение на самом деле примерно а 95% anemic.

    Рич или не рич модель теперь определяется количеством DTO требуемых для произвольных выборок? Ну ладно, можешь считать, что все пишут анемик, you win.

    G>Так что не попадает null куда не надо.


    Так у тебя нулл нормальное значение для данных.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[40]: Anemic Domain Model vs Rich Domain Model
    От: meowth  
    Дата: 01.06.09 11:57
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    G>>Только это получается не rich

    G>>Создавая везде кастомны еобъекты для представления результатов выоборок толку от domain objects и логики в них не остается.
    G>>Поэтому хорошее rich приложение на самом деле примерно а 95% anemic.

    Z>Рич или не рич модель теперь определяется количеством DTO требуемых для произвольных выборок? Ну ладно, можешь считать, что все пишут анемик, you win.


    Короче, я думаю, что мы проиграли этот спор Потому что мы пользуемя anemic DTO и (о боже!) сервисами. Спорить далее не вижу смысла.
    Re[32]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 12:22
    Оценка: +1
    Здравствуйте, WFrag, Вы писали:

    WF>Здравствуйте, gandjustas, Вы писали:


    WF>>>Не совсем. События, по которым определяется список сообщений для отправки, генерирует именно наша система, обновляя ровно ту же запись, что используется в сообщениях, на основании данных нескольких внешних систем (которые, вообще говоря, могут выдавать даже противоречивые данные).

    G>>Ниче не понял.
    G>>Если у вас события отделены от состояния (например рейса), то все ок.
    G>>Если нет — то это нарушение SRP.

    WF>Схема такая: Пришло N событий => на их основании обновляем рейс => получаем M новых событий => уже по этим событиям определяем сообщения => для каждого полученного события по рейсу (+связанные сущности типа аэропорт, перевозчик) и событию (которое содержит старое и новое значение) генерируем сообщение по шаблону.


    WF>Чтобы на втором шаге обновить рейс нам просто необходимо его загрузить. Потому что обновление — это не просто update аттрибутов. Это информация типа «такой-то источник считает, что время отрыва от полосы — вот такое». Надо загрузить рейс, проанализировать его, и действовать соответственно. Можно проигнорировать обновление («noise filter» сработал), можно просто установить/обновить аттрибут, можно установить аттрибут и поменять состояние.


    WF>Можно, конечно, на первом этапе грузить те аттрибуты, которые пришли в исходных событиях + ещё пара аттрибутов, а на втором ещё раз грузить рейс, но уже с теми аттрибутами, которые нужны для генерации сообщения. Но это уже два запроса.


    Я уе не улавливаю всех деталей. Поэтому не смогу адекватно что-то сказать.


    G>>При динамическом составлении проекции тоже кешированные данные не помогут.

    WF>Так речь-то о том, что как составлять проекцию и при этом делать это простым способом — мне совершенно не очевидно. Даже просто парсить шаблон и осознавать, какие колонки нам нужны — это уже добавит сложности.

    Накаких сложнойстей. Код с применением EF:
    //templates - шаблоны сообщений
    
    var parser = new Regex(@"\${\s*([^}]*)\s*}", RegexOptions.Compiled);
    var fields = (from t in templates
                  from m in parser.Matches(t).OfType<Match>()
                  select m.Groups[1].Value)
                 .Distinct();
    
    var projection = string.Join(", ", fields.Select(f => "it." + f).ToArray());
    
    ObjectContext _context = new SomeContext();
    var q = _context.CreateQuery<DbDataRecord>("some query");
    //Filters for query
    q = q.Select(projection);
    var values = q.First();
    
    var nameValueMap = fields
        .Select((f, i) => new { Value = values.GetValue(i), Field = f })
        .ToDictionary(p => p.Field, p => p.Value);
    var texts = from t in templates
                select parser.Replace(t, m => nameValueMap[m.Groups[1].Value].ToString());
    Re[32]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 12:26
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Ну тут ты совсем мимо кассы.

    G>>Считаем обращения к связанным данным в примере синклера.
    Z>Пример синклера в рич модели выглядит обычно так
    Автор: Ziaw
    Дата: 01.06.09
    :


    G>>В Linq такой запрос бдет выглядеть так:

    Z>Такой запрос пишется в жирной модели точно также и транслируется в тот же сиквел.
    Да ну? И в каком месте модели пишется такой запрос? В объекте кастомера?

    G>>Во-вторых сразу видно что танется из базы и можно вполне резонно задавать вопросы зачем это тянется.

    Z>Обращение к данным в рич модели тоже видно невооруженным глазом.
    Ну да. Только тот пример, кторый написал синклер — реальность десятки таких видел, а то что ты выдумываешь — случается ооооочень редко.

    G>>В-третьих — даже такой запрос выполнится быстрее (причем гораздо быстрее), чем 5n+2 из примера синклера.

    Z>1+N на самом деле.
    Один, только что проверил.
    Re[40]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 12:27
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    Z>>>Воспринимай ее также в рич модели, если тебе не нужен этот паттерн, зачем его применять?

    G>>В rich так не получится, там реальные объекты и кучи запросов.
    Z>В рич легко выполнять те же самые запросы, что и в анемик. Нет никаких препятствий для этого.
    Куда запросы помещать?

    G>>Так что не попадает null куда не надо.

    Z>Так у тебя нулл нормальное значение для данных.
    Это ты так думаешь, а EF так не думает
    Re[33]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 12:35
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>>>В-третьих — даже такой запрос выполнится быстрее (причем гораздо быстрее), чем 5n+2 из примера синклера.

    Z>>1+N на самом деле.
    G>Один, только что проверил.

    Это я че-то не о том подумал....

    Написал пример синклера а Linq2SQL — действительно 5n+2 получилось.
    Re: Anemic Domain Model vs Rich Domain Model
    От: Blazkowicz Россия  
    Дата: 01.06.09 12:35
    Оценка:
    Здравствуйте, GlebZ, Вы писали:

    GZ>Но для Rich, нужно сразу запастись инструментальными средствами, типа Hibernate(у которого есть чудный кэш), и средства сериализации/десериализации. Это сгладит недостатки модели.

    Какое отношение к вопросу имеет ORM?
    Re[34]: Anemic Domain Model vs Rich Domain Model
    От: meowth  
    Дата: 01.06.09 12:36
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Это я че-то не о том подумал....

    G>Написал пример синклера а Linq2SQL — действительно 5n+2 получилось.

    Сорри, поинтересуюсь -- это доказывает, что rich и LL -- это плохо?
    Re[35]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 12:40
    Оценка:
    Здравствуйте, meowth, Вы писали:

    M>Здравствуйте, gandjustas, Вы писали:


    G>>Это я че-то не о том подумал....

    G>>Написал пример синклера а Linq2SQL — действительно 5n+2 получилось.

    M>Сорри, поинтересуюсь -- это доказывает, что rich и LL -- это плохо?

    Да, потому что толкает к написанию тормозящего кода.
    Кеш помогает скрыть проблему, но не избавляет от нее.
    Re[36]: Anemic Domain Model vs Rich Domain Model
    От: Blazkowicz Россия  
    Дата: 01.06.09 12:44
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    M>>Сорри, поинтересуюсь -- это доказывает, что rich и LL -- это плохо?

    G>Да, потому что толкает к написанию тормозящего кода.
    G>Кеш помогает скрыть проблему, но не избавляет от нее.
    Дык это как бы и есть идеология подобных ORM. Написать максимально быстро, при этом не важно как работает. Затем соптимизать критические участки до желаемой производительности.
    Re[37]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 12:49
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Здравствуйте, gandjustas, Вы писали:


    M>>>Сорри, поинтересуюсь -- это доказывает, что rich и LL -- это плохо?

    G>>Да, потому что толкает к написанию тормозящего кода.
    G>>Кеш помогает скрыть проблему, но не избавляет от нее.
    B>Дык это как бы и есть идеология подобных ORM. Написать максимально быстро, при этом не важно как работает. Затем соптимизать критические участки до желаемой производительности.
    В случае если логика сильно опирается на LL, то оптимизация заключается в переписывании.

    Помотри пример синклера выше по теме и более оптимальный вариант на Linq. Linq запрос короче, декларативнее и на порядок быстрее работает.
    Поэтому rich и LL однозначно сливают.

    Другое дело что в с Linq не получится работать с объектами. Уже нету кастомера в классе которого можно написать такой запрос.
    Re[38]: Anemic Domain Model vs Rich Domain Model
    От: Blazkowicz Россия  
    Дата: 01.06.09 13:01
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>В случае если логика сильно опирается на LL, то оптимизация заключается в переписывании.

    В случае Hibernate, вместо переписывания можно просто указать какие именно ассоциации хочется загрузить сразу же без "лени". Многие другие ORM умеют так же.

    G>Помотри пример синклера выше по теме и более оптимальный вариант на Linq. Linq запрос короче, декларативнее и на порядок быстрее работает.

    Возможно.

    G>Поэтому rich и LL однозначно сливают.

    :)
    Re[39]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 13:07
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Здравствуйте, gandjustas, Вы писали:


    G>>В случае если логика сильно опирается на LL, то оптимизация заключается в переписывании.

    B>В случае Hibernate, вместо переписывания можно просто указать какие именно ассоциации хочется загрузить сразу же без "лени". Многие другие ORM умеют так же.
    Посмотри еще раз прмиер синклера.
    Там запрос получает список категорий товаров, купленных заданным кастомером в заданный период.
    Загрузкой объектов, хоть с LL, хоть без него не сильно оптимизируешь. Хотя во многих случаях eager loading помогает ускорить работу.

    G>>Помотри пример синклера выше по теме и более оптимальный вариант на Linq. Linq запрос короче, декларативнее и на порядок быстрее работает.

    B>Возможно.
    Гарантированно
    Re[32]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 01.06.09 16:10
    Оценка: +1
    Здравствуйте, Ziaw, Вы писали:

    Z>Но поднимет он их, вероятно, на порядок больше чем требуется. А в рич модели тупой код будет примерно таким:

    Z>
    Z>foreach(Order o in s.Filter(customer.Orders, "where Date between ? and ?", new[] {startDate, endDate}) // 1 запрос
    Z>{
    Z>    foreach(String name in 
    Z>        s.Filter(o.Items, "select Product.Category.Name where Product.Category in (?)", new[] {categories}) // +N запросов
    Z>    {
    Z>        categories.Add(name);
    Z>    }
    Z>}
    Z>

    Z>Дальнейшая оптимизация нужна только если N ожидатеся реально большим.
    Прекрасно. То есть мы всё-таки поднимаем все заказы за период. Поздравляю, быстродействие падает линейно с увеличением диапазона дат. Да, конечно же N ожидается реально большим. Ну, не там, где разработчик это тестирует, а в боевой базе. Кстати, как работает ваш код — что там за {categories} в параметрах, и что за фильтр вы собрались накладывать на o.Items? По-видимому, императивная запись провоцирует ошибки на ровном месте.

    Z>Именно потому, что он ленив, он не будет переделывать контракт метода с foreach в который передавался кастомер. Или всетаки такие методы сами выбирают нужные для себя данные?

    Ничего не понимаю. Какой контракт? В анемичной модели у метода с самого начала три параметра: идентификатор кастомера, две даты. Разработчик оставлен наедине с этими параметрами. Навигация по ордерам — последнее, что придет ему в голову. Потому, что в анемичной модели для этого придется написать вручную код, который поднимает их в память.
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[28]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 01.06.09 16:12
    Оценка:
    Здравствуйте, WFrag, Вы писали:
    WF>Обновление записи — это не просто SQL-ный update. Нужно посмотреть предыдущие значения аттрибутов (и запомнить их), обновить их (прогнав каждое изменение через «noise» фильтр, обладающий правом «вето») и состояние рейса (если изменилось), получить список произошедших изменений.
    Я ничего не понял, но это абсолютно неважно. Важно вот что: у вас в любом случае есть некий шаблон. Именно он определяет, что за данные потребуются. Выполнять загрузку данных до его разбора нет причины.

    WF>Это условное понятие. Понятно, что кешировать можно всё, что захочется. Но так как нам не хочется возиться с когерентностью кешей и кластерными блокировками (тем более, что СУБД действительно лучше с этим справится), то там, где мы можем позволить временное нарушение консистентности (пока инвалидация пройдёт по узлам) — мы используем кеш (с любым expiration-ом, какой нам нужен), там где нет — увы.

    Это всё очень хорошо, но мне по-прежнему непонятно, при чём здесь Lazy Load. Ну, кроме того, что на него можно полагаться как на fallback — там, где модель с явной загрузкой просто упадёт, LL будет делать вид, что работает — пусть и ценой чудовищной неэффективности.
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[33]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 01.06.09 16:13
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Да ну? И в каком месте модели пишется такой запрос? В объекте кастомера?


    Рич модель не ограничивает тебя. Запрос ты можешь поместить в сервис, маппинг или сам объект. Надо всего лишь подумать, в каком месте он будет удобнее в использовании для остального кода.

    G>Ну да. Только тот пример, кторый написал синклер — реальность десятки таких видел, а то что ты выдумываешь — случается ооооочень редко.


    Не нужно пытаться работать с моделью игнорируя тот факт, что это отражение персистных данных. Те, кто использует РСУБД не ноют, что почти любой сложный запрос можно написать десятком жутко тормозных способов и всего один-два дадут оптимальный план. Не ноют, что навигационный доступ в ней мягко говоря отсутствует. Что для быстроты запросов надо тюнить схему добавляя индексы, материализовывать вьюхи, денормализовывать данные. Что обрабатывать данные в циклах почти наверняка плохая идея. Большинство просто использует ее сильные стороны и радуется жизни.

    Z>>1+N на самом деле.

    G>Один, только что проверил.

    Один он если данные получать одним запросом. В обеих моделях он будет один с если включить мозг и написать его, сложность написания и там и там одинакова. N+1 будет в рич модели если включить мозг не полностью, а всего лишь следуя культуре кода.
    Re[34]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 16:37
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Да ну? И в каком месте модели пишется такой запрос? В объекте кастомера?


    Z>Рич модель не ограничивает тебя. Запрос ты можешь поместить в сервис, маппинг или сам объект. Надо всего лишь подумать, в каком месте он будет удобнее в использовании для остального кода.

    Ну да, самый правильный rich — это anemic.

    G>>Ну да. Только тот пример, кторый написал синклер — реальность десятки таких видел, а то что ты выдумываешь — случается ооооочень редко.


    Z>Не нужно пытаться работать с моделью игнорируя тот факт, что это отражение персистных данных.

    Ух ты. Мне недавно кто-то доказывал что PI — само главное в rich.

    Определитесь какими свойствами должна обладать rich модель чтобы быть по-настоящему rich.
    Re[29]: Anemic Domain Model vs Rich Domain Model
    От: WFrag США  
    Дата: 01.06.09 17:06
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    WF>>Обновление записи — это не просто SQL-ный update. Нужно посмотреть предыдущие значения аттрибутов (и запомнить их), обновить их (прогнав каждое изменение через «noise» фильтр, обладающий правом «вето») и состояние рейса (если изменилось), получить список произошедших изменений.

    S>Я ничего не понял, но это абсолютно неважно. Важно вот что: у вас в любом случае есть некий шаблон. Именно он определяет, что за данные потребуются. Выполнять загрузку данных до его разбора нет причины.

    То есть предлагается грузить данные два раза. Первый раз — для их обновления (это обязательно, так как старые значения учавствуют в расчёте новых, это то, что я пытаюсь донести до тебя и gandjustas-а, обычный update тут не сработает), второй раз для генерации сообщения по шаблону(-ам). Причём какие шаблоны потребуются тоже определяется на первых шагах — при обновлении старой записи.

    Не понимаю, в чём выгода. Моё решение — не требует усилий и работает удовлетворительно. Вы на пару предлагаете какие-то усложнения без видимых преимуществ

    S>Это всё очень хорошо, но мне по-прежнему непонятно, при чём здесь Lazy Load.


    При том, что не нужно прописывать загрузку явно и при этом иметь достаточный контроль для оптимизации. Надо — кешируем, не надо — загружаем хоть сразу, хоть отложено.
    Re[30]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 01.06.09 21:22
    Оценка:
    Здравствуйте, WFrag, Вы писали:

    WF>Здравствуйте, Sinclair, Вы писали:


    WF>>>Обновление записи — это не просто SQL-ный update. Нужно посмотреть предыдущие значения аттрибутов (и запомнить их), обновить их (прогнав каждое изменение через «noise» фильтр, обладающий правом «вето») и состояние рейса (если изменилось), получить список произошедших изменений.

    S>>Я ничего не понял, но это абсолютно неважно. Важно вот что: у вас в любом случае есть некий шаблон. Именно он определяет, что за данные потребуются. Выполнять загрузку данных до его разбора нет причины.

    WF>То есть предлагается грузить данные два раза. Первый раз — для их обновления (это обязательно, так как старые значения учавствуют в расчёте новых, это то, что я пытаюсь донести до тебя и gandjustas-а, обычный update тут не сработает), второй раз для генерации сообщения по шаблону(-ам). Причём какие шаблоны потребуются тоже определяется на первых шагах — при обновлении старой записи.

    Любое изменение данных можно выполнить с помощью одного update без вытягивания данных. Правда этот update может быть слишком сложным.
    Тогда есть хороший вариант для MS SQL — SQL CLR.
    Таким образом вашу задачу модно выполнить одним (!) обращением к БД. Будет отправлен батч из двух команд — запуск нужной хранимки и выборка необходимых данных (возможно тоже хранимкой).
    Только применение всех этих способов может усложнить в разы поддержку решения.
    Если бы указанный этот случай был боттлнеком, то имело бы смысл заморачиваться, а если нет, то и смысла в этом нету.


    WF>Не понимаю, в чём выгода. Моё решение — не требует усилий и работает удовлетворительно. Вы на пару предлагаете какие-то усложнения без видимых преимуществ

    Это как раз тот случай, когда тупое решение оказывается оптимальным, и rich с anemic тут равны.
    Но это в основном проблема слабых средств динамического построения запросов (особенно DML) и невозможности батчинга запросов.
    Re[18]: Anemic Domain Model vs Rich Domain Model
    От: koandrew Канада http://thingselectronic.blogspot.ca/
    Дата: 02.06.09 01:23
    Оценка:
    Здравствуйте, Лобанов Игорь, Вы писали:

    ЛИ>Есть разные варианты:

    ЛИ>1) Самый простой: кэш локален на каждом узле, согласованность обеспечивается синхронной инвалидацией;
    ЛИ>2) Для кэша используются отдельные специализированные узлы. Это стандартное решение для создания высоконагруженных приложений на платформе LAMP+memcached;
    ЛИ>3) Самый сложный: данные в кэше автоматически реплицируются и балансируются между узлами, что обеспечивает высокую надёжность. Ключевые слова: consistent hashing, in-memory data grid, cache partitioning. Сейчас (по крайней мере в JEE) такое умеют только дорогие проприетарные продукты типа Oracle Coherence, но на подходе и open source альтернативы.

    А вот теперь объясните мне пожалуйста, ради каких таких серьёзных и неоспоримых преимуществ стоит городить весь этот огород? Когда проблема элементарно решается reverse http proxy + proxy + клиентское кэширование — если мы говорим про веб (хотите узнать как — спросите у Синклера — он объяснит, если, конечно, его не заломает объяснять это в 1000001-й раз)...
    [КУ] оккупировала армия.
    Re[33]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 02:32
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>Прекрасно. То есть мы всё-таки поднимаем все заказы за период. Поздравляю, быстродействие падает линейно с увеличением диапазона дат. Да, конечно же N ожидается реально большим. Ну, не там, где разработчик это тестирует, а в боевой базе.


    Тупой императивный код можно накрутить в обеих моделях, да в рич это делается чуть проще.

    S>Кстати, как работает ваш код — что там за {categories} в параметрах, и что за фильтр вы собрались накладывать на o.Items?

    S>По-видимому, императивная запись провоцирует ошибки на ровном месте.

    Нее, я вообще не пытался понять твой алгоритм. Просто переписал по быстрому, в стиле доступа к рич модели, оттуда и ошибка. Хотел лишь показать, что даже тупой код доступа в рич не настолько плох, как ты пытаешься продемонстрировать. Даже не сообразил сразу, что это даже не логика, а метод из DAO, имхо, даже самые тупые программисты не пишут в DAL такой код.

    S>Ничего не понимаю. Какой контракт? В анемичной модели у метода с самого начала три параметра: идентификатор кастомера, две даты. Разработчик оставлен наедине с этими параметрами. Навигация по ордерам — последнее, что придет ему в голову. Потому, что в анемичной модели для этого придется написать вручную код, который поднимает их в память.


    Ганжустас утверждал, что бизнес методы в АДМ не вытаскивают данные для себя, а принимают их уже загруженными как аргументы. Сорри, сейчас из браузера, не найду конкретный пост. Ты не согласен? Альтернатива? Каждый метод в транзакции сам добывает данные для себя?
    Re[34]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 02.06.09 03:39
    Оценка:
    Здравствуйте, Ziaw, Вы писали:
    Z>Тупой императивный код можно накрутить в обеих моделях, да в рич это делается чуть проще.
    Именно.
    Z>Нее, я вообще не пытался понять твой алгоритм. Просто переписал по быстрому, в стиле доступа к рич модели, оттуда и ошибка. Хотел лишь показать, что даже тупой код доступа в рич не настолько плох, как ты пытаешься продемонстрировать.
    Ага. Но вместо этого именно что продемонстрировал, что он именно настолько плох.

    Z>Ганжустас утверждал, что бизнес методы в АДМ не вытаскивают данные для себя, а принимают их уже загруженными как аргументы. Сорри, сейчас из браузера, не найду конкретный пост.

    Z> Ты не согласен? Альтернатива? Каждый метод в транзакции сам добывает данные для себя?
    Ты его неправильно понял. Ентити не вытягивают данные для себя. А бизнес код — именно что вытягивает. В АДМ бизнес-код собственно весь и состоит из доставания данных и их модификации. Фактически, это transaction script на стероидах — то есть написанный на языке с развитыми возможностями по декомпозиции.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[35]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 05:46
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    Z>>Тупой императивный код можно накрутить в обеих моделях, да в рич это делается чуть проще.

    S>Именно.

    Про чуть проще я и не спорил никогда. Ключевое слово чуть.

    S>Ты его неправильно понял. Ентити не вытягивают данные для себя. А бизнес код — именно что вытягивает. В АДМ бизнес-код собственно весь и состоит из доставания данных и их модификации. Фактически, это transaction script на стероидах — то есть написанный на языке с развитыми возможностями по декомпозиции.


    Я его правильно понял, вот тут и возникает проблема следующая из такого тезиса

    Если два сервиса пользуются одиними и теми же данными, то данные им передает вызывающий код.

    (здесь
    Автор: gandjustas
    Дата: 01.06.09
    )

    Расширяем транзакшн скрипт, и понимаем, что данные которые требовались в методе А теперь нужны и в методе Б. Надо перелопачивать контракты сервисов, так как метод А раньше доставал их самостоятельно. В процессе перелопачивания мы узнаем, что метод А вызывается еще в 10 транзакшн скриптах, теперь в каждом из них придется написать код готовящий данные для метода А.

    А в рич модели один раз поднятые данные достаются еще раз легко и непринужденно, голова об этом не болит.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[36]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 06:07
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Расширяем транзакшн скрипт, и понимаем, что данные которые требовались в методе А теперь нужны и в методе Б. Надо перелопачивать контракты сервисов, так как метод А раньше доставал их самостоятельно. В процессе перелопачивания мы узнаем, что метод А вызывается еще в 10 транзакшн скриптах, теперь в каждом из них придется написать код готовящий данные для метода А.

    Не выдумывай небылицы.
    Доставангие данных происходит на "верхнем уровне", полученные данные передаются методам БЛ, которые не занимаются доставанием данных.
    Верхний уровень соотвествует одному transaction script, поэтому вызывается в одном, максимум двух местах. Основная часть БЛ состоит из маленьких методов, собранных в сервисы.

    Z>А в рич модели один раз поднятые данные достаются еще раз легко и непринужденно, голова об этом не болит.


    5n+2 вместо одного запроса.
    А голова рано или позно при таком подходе болеть начинает. Кеш тоже небесконечный, чем больше объемы кешированных данных, тем больше промахов будет и чаще придется в базу бегать за даннми.
    Re[34]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 06:08
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, Sinclair, Вы писали:


    S>>Прекрасно. То есть мы всё-таки поднимаем все заказы за период. Поздравляю, быстродействие падает линейно с увеличением диапазона дат. Да, конечно же N ожидается реально большим. Ну, не там, где разработчик это тестирует, а в боевой базе.


    Z>Тупой императивный код можно накрутить в обеих моделях, да в рич это делается чуть проще.

    Сложноси такие же. В рич надо чуть меньше думать, чтобы сделать тупой код.
    Re[36]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 02.06.09 06:21
    Оценка: 1 (1)
    Здравствуйте, Ziaw, Вы писали:

    Z>Расширяем транзакшн скрипт, и понимаем, что данные которые требовались в методе А теперь нужны и в методе Б. Надо перелопачивать контракты сервисов, так как метод А раньше доставал их самостоятельно.

    Не думаю, что это жизненный пример. Но даже если контракт и поменяется (что при нормальном проектировании маловероятно), то не составит труда отрефакторить код.

    В метод A будет передаваться, допустим, IEnumerable<something>. Метод A со старой сигнатурой будет вызывать новый метод A, передавая в него тот IQueryable<something>, который раньше был зашит вовнутрь.
    А наш метод B (или кто там оркеструет оба метода) будет передавать один и тот же экземпляр в оба метода, благодаря чему материализация случится только один раз. А может быть и вообще не случится — если на основе этого IQueryable формируется некий другой запрос.

    Z>А в рич модели один раз поднятые данные достаются еще раз легко и непринужденно, голова об этом не болит.

    Ну-ну. Вы слишком много думаете о поднятии данных, и слишком мало — о том, что на самом деле нужно сделать. Очень характерный пример с ордер айтемами тут уже был. Там, где анемичная модель провоцирует построение запросов, в которых пересчёты всех хранимых агрегатов делаются на серверной стороне, рич модель провоцирует "батч моду LL". От этой батч моды голова, конечно, не болит. Болит другое место — которым ощущаются проблемы с перформансом из-за увеличения площади локов, времени их удержания, и роста трафика между СУБД и апп-сервером.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[37]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 06:26
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Не выдумывай небылицы.

    G>Доставангие данных происходит на "верхнем уровне", полученные данные передаются методам БЛ, которые не занимаются доставанием данных.
    G>Верхний уровень соотвествует одному transaction script, поэтому вызывается в одном, максимум двух местах. Основная часть БЛ состоит из маленьких методов, собранных в сервисы.

    Вы с Синклером договоритесь пожалуйста, или спорьте в разных ветках. Он утверждает, что данные достаются там где они понадобились, главное чтобы это где-то не находилось в классе entity.


    Z>>А в рич модели один раз поднятые данные достаются еще раз легко и непринужденно, голова об этом не болит.

    G>
    G>5n+2 вместо одного запроса.

    Я видимо в пустоту пишу. Повторю, пример Синклера это пример тупейшего кода. Даже просто тупой код дает N+1, такойже тупой можно написать в ADM и он будет делать столько же запросов. Это такой прием демагогии, написать тупейший пример и потом ссылаться на него как на ключевой недостаток модели, рекомендую воздерживаться от постоянного его применения, чтобы дискуссия продолжала оставаться конструктивной.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[37]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 06:50
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    Z>>Расширяем транзакшн скрипт, и понимаем, что данные которые требовались в методе А теперь нужны и в методе Б. Надо перелопачивать контракты сервисов, так как метод А раньше доставал их самостоятельно.

    S>Не думаю, что это жизненный пример. Но даже если контракт и поменяется (что при нормальном проектировании маловероятно), то не составит труда отрефакторить код.

    Я с такими примерами сталкиваюсь при развитии и поддержке анемичной модели, так что жизненный.

    S>В метод A будет передаваться, допустим, IEnumerable<something>. Метод A со старой сигнатурой будет вызывать новый метод A, передавая в него тот IQueryable<something>, который раньше был зашит вовнутрь.

    S>А наш метод B (или кто там оркеструет оба метода) будет передавать один и тот же экземпляр в оба метода, благодаря чему материализация случится только один раз. А может быть и вообще не случится — если на основе этого IQueryable формируется некий другой запрос.

    Интересно. Но осталась еще проблема, надо как-то узнать, что метод А со старой сигнатурой дергает в нашей транзакции те же данные, что сейчас нужны для метода Б. Т.е. для правильно расширения скрипта нам надо протолкаться по всем вытаскиваемым во всех ветках алгоритма данным, увидеть, что метода А уже тащит те же данные, создать перегрузку, вытащить их самостоятельно, передать те же данные в метод Б. И надеяться, что требование одинаковых данных для А и Б достаточно стабильно.

    Z>>А в рич модели один раз поднятые данные достаются еще раз легко и непринужденно, голова об этом не болит.

    S>Ну-ну. Вы слишком много думаете о поднятии данных, и слишком мало — о том, что на самом деле нужно сделать. Очень характерный пример с ордер айтемами тут уже был.

    Это неверный вывод из примера. Тебе показалось, что я попытался решить задачу в рич модели, а я всего лишь показал какой будет типичный тупой код в рич модели. Он всетаки выигрывает у твоего примера примерно в 5 раз по быстродействию.

    S>Там, где анемичная модель провоцирует построение запросов, в которых пересчёты всех хранимых агрегатов делаются на серверной стороне, рич модель провоцирует "батч моду LL". От этой батч моды голова, конечно, не болит. Болит другое место — которым ощущаются проблемы с перформансом из-за увеличения площади локов, времени их удержания, и роста трафика между СУБД и апп-сервером.


    Я думал мы уже обсосали этот пример и я признал определенный недостаток рич модели: при написании кода в ней надо думать над тем, что достается из базы, хотя и некоторым кажется, что это необязательно. Мне это можно больше не доказывать и в каждом посте не упоминать об этом. Пожалей свое и мое время.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[38]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 06:51
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Не выдумывай небылицы.

    G>>Доставангие данных происходит на "верхнем уровне", полученные данные передаются методам БЛ, которые не занимаются доставанием данных.
    G>>Верхний уровень соотвествует одному transaction script, поэтому вызывается в одном, максимум двух местах. Основная часть БЛ состоит из маленьких методов, собранных в сервисы.

    Z>Вы с Синклером договоритесь пожалуйста, или спорьте в разных ветках. Он утверждает, что данные достаются там где они понадобились, главное чтобы это где-то не находилось в классе entity.

    Мы про разные аспекты говорим. Он про доставание данных, а я про обработку того что достали.


    Z>>>А в рич модели один раз поднятые данные достаются еще раз легко и непринужденно, голова об этом не болит.

    G>>
    G>>5n+2 вместо одного запроса.

    Z>Я видимо в пустоту пишу. Повторю, пример Синклера это пример тупейшего кода. Даже просто тупой код дает N+1, такойже тупой можно написать в ADM и он будет делать столько же запросов.

    Не надо себя убеждать в этом.
    Во-первых Linq запрос на вытягивание данных получается короче, писать тупой код становится сложнее, так как надо больше писать.
    Во-вторых когда начинаешь писать запросы оказывается что часть действий может быть выполнена в БД, с гораздо большей эффективностью, чем в приложении. Объем кода от этого неувеличивается, а зачастую уменьшается так как запросы более декларативны.

    Z>Это такой прием демагогии, написать тупейший пример и потом ссылаться на него как на ключевой недостаток модели, рекомендую воздерживаться от постоянного его применения, чтобы дискуссия продолжала оставаться конструктивной.

    Это не просто тупой пример. Это код, который вполне может быть написан с применением LL.
    Примеры которые ты выдумываешь вряд ли будут когда-то написаны, так как они сложнее правильного варианта.
    Re[38]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 02.06.09 07:31
    Оценка: :)
    Здравствуйте, Ziaw, Вы писали:


    Z>Интересно. Но осталась еще проблема, надо как-то узнать, что метод А со старой сигнатурой дергает в нашей транзакции те же данные, что сейчас нужны для метода Б. Т.е. для правильно расширения скрипта нам надо протолкаться по всем вытаскиваемым во всех ветках алгоритма данным, увидеть, что метода А уже тащит те же данные, создать перегрузку, вытащить их самостоятельно, передать те же данные в метод Б. И надеяться, что требование одинаковых данных для А и Б достаточно стабильно.

    Это всё какая-то малоинтересная история. Что значит "узнать, что он дёргает"? Изменение делается согласованно, одним девелопером. Я не понимаю, в чём ваша проблема. Проталкиваться никуда не надо, потому что всё лежит перед глазами; все методы имеют нормальные имена и определённую семантику. Приведите пример ситуации — какой код был написан, какое изменение потребовалось, что по-вашему придётся переделать. Я постараюсь ответить, как правильно менять код в приведённом случае.

    Z>Это неверный вывод из примера. Тебе показалось, что я попытался решить задачу в рич модели, а я всего лишь показал какой будет типичный тупой код в рич модели. Он всетаки выигрывает у твоего примера примерно в 5 раз по быстродействию.

    У моего примера он проигрывает по быстродействию на три порядка. О чём мы вообще говорим — о бесконечно тормозном решении по сравнению с безгранично тормозным?
    Я, кстати, говорил не про этот пример. А про пример, приведенный meowth, где при изменении одного OrderItem в память поднимается вся коллекция детей ордера для пересчёта total. О да, тут мы уверены в енфорсинге всех бизнес рулов. Ну, конечно, batch in LL рулит неимоверно.
    Это по сравнению с кодом вида update _order set amt = (select sum(amount) from orderItem oi where orderId = @orderID) where id = @orderId. Ага-ага. Нет, у меня определенно дефицит сарказма.

    Z>Я думал мы уже обсосали этот пример и я признал определенный недостаток рич модели: при написании кода в ней надо думать над тем, что достается из базы, хотя и некоторым кажется, что это необязательно. Мне это можно больше не доказывать и в каждом посте не упоминать об этом. Пожалей свое и мое время.

    Не понял — а о чём тогда вы хотите поговорить? Я не собираюсь спорить с тезисом "иногда, при осторожном использовании, рич модель сосёт не слишком сильно по сравнению с анемик".
    Я просто всё еще жду жызненного примера, где рич порвёт анемик на тряпки. А то получается, что супергуру рич модели приводят в её защиту примеры, которые заведомо чудовищно неэффективны. Еще раз: не как пример "наивного" кода. А как пример того, что пишет компетентный девелопер в рич модели. Кому вы хотите продать рич модель? С такой-то аргументацией?
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[39]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 07:47
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Не надо себя убеждать в этом.

    G>Во-первых Linq запрос на вытягивание данных получается короче, писать тупой код становится сложнее, так как надо больше писать.
    G>Во-вторых когда начинаешь писать запросы оказывается что часть действий может быть выполнена в БД, с гораздо большей эффективностью, чем в приложении. Объем кода от этого неувеличивается, а зачастую уменьшается так как запросы более декларативны.

    Давай так, будем говорить за себя. Рич модель лично тебя делает настолько тупым, что ты начинаешь забывать, что БД эффективнее делает запросы?

    Z>>Это такой прием демагогии, написать тупейший пример и потом ссылаться на него как на ключевой недостаток модели, рекомендую воздерживаться от постоянного его применения, чтобы дискуссия продолжала оставаться конструктивной.

    G>Это не просто тупой пример. Это код, который вполне может быть написан с применением LL.
    G>Примеры которые ты выдумываешь вряд ли будут когда-то написаны, так как они сложнее правильного варианта.

    Зато правильный вариант точно такой же как и линковский:
      var q = s.CreateQuery(@"select distinct i.Product.Category.Name 
                        from Order o join o.OrderItems i 
                        where o.Date between :startDate and :endDate")
                .SetParameter("startDate", startDate)
                .SetParameter("endDate", endDate)
                .List<string>();


    А теперь напиши линковский запрос в случае, когда твоя анемик модель действительно анемик. Т.е. у объектов нет навигационные связи только в виде OrderId в OrderItem.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[39]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 07:57
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>Я, кстати, говорил не про этот пример. А про пример, приведенный meowth, где при изменении одного OrderItem в память поднимается вся коллекция детей ордера для пересчёта total. О да, тут мы уверены в енфорсинге всех бизнес рулов. Ну, конечно, batch in LL рулит неимоверно.

    S>Это по сравнению с кодом вида update _order set amt = (select sum(amount) from orderItem oi where orderId = @orderID) where id = @orderId. Ага-ага. Нет, у меня определенно дефицит сарказма.

    Что-то я не понял, каким ОРМ тулом мы делаем подобные действия? При чем тут модель? Прямой запрос к базе на чистом сиквеле делается в любой модели и к выбраной модели не относится вообще.

    Z>>Я думал мы уже обсосали этот пример и я признал определенный недостаток рич модели: при написании кода в ней надо думать над тем, что достается из базы, хотя и некоторым кажется, что это необязательно. Мне это можно больше не доказывать и в каждом посте не упоминать об этом. Пожалей свое и мое время.

    S>Не понял — а о чём тогда вы хотите поговорить? Я не собираюсь спорить с тезисом "иногда, при осторожном использовании, рич модель сосёт не слишком сильно по сравнению с анемик".
    S>Я просто всё еще жду жызненного примера, где рич порвёт анемик на тряпки. А то получается, что супергуру рич модели приводят в её защиту примеры, которые заведомо чудовищно неэффективны. Еще раз: не как пример "наивного" кода. А как пример того, что пишет компетентный девелопер в рич модели. Кому вы хотите продать рич модель? С такой-то аргументацией?

    Я где-то утверждал, что она рвет анемик на тряпки? Я утверждал, что она может стать проще для поддержки внесения изменений. Это сложно доказать. Я в свою очередь жду пример сценария, а не императивного кода, где рич модель не может быть эффективна.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[40]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 07:59
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Не надо себя убеждать в этом.

    G>>Во-первых Linq запрос на вытягивание данных получается короче, писать тупой код становится сложнее, так как надо больше писать.
    G>>Во-вторых когда начинаешь писать запросы оказывается что часть действий может быть выполнена в БД, с гораздо большей эффективностью, чем в приложении. Объем кода от этого неувеличивается, а зачастую уменьшается так как запросы более декларативны.

    Z>Давай так, будем говорить за себя. Рич модель лично тебя делает настолько тупым, что ты начинаешь забывать, что БД эффективнее делает запросы?

    Какой-то наезд не в тему

    Z>>>Это такой прием демагогии, написать тупейший пример и потом ссылаться на него как на ключевой недостаток модели, рекомендую воздерживаться от постоянного его применения, чтобы дискуссия продолжала оставаться конструктивной.

    G>>Это не просто тупой пример. Это код, который вполне может быть написан с применением LL.
    G>>Примеры которые ты выдумываешь вряд ли будут когда-то написаны, так как они сложнее правильного варианта.

    Z>Зато правильный вариант точно такой же как и линковский:

    Z>
    Z>  var q = s.CreateQuery(@"select distinct i.Product.Category.Name 
    Z>                    from Order o join o.OrderItems i 
    Z>                    where o.Date between :startDate and :endDate")
    Z>            .SetParameter("startDate", startDate)
    Z>            .SetParameter("endDate", endDate)
    Z>            .List<string>();
    Z>

    Ну и в какой класс модели ты этот запрос засунешь?
    Если вся программа на таких запросах, то rich не остается.

    Кроме того текстовые запросы таят те же проблемы, что и SQL.
    Напрмер у тебя в куче запросов надо выбирать ордеры в диапазоне дат, в твоем случае каждый запрос придется дублировать выделенный кусок кода, или заниматься конкатенацией строк (прощай читаемость).


    Z>А теперь напиши линковский запрос в случае, когда твоя анемик модель действительно анемик. Т.е. у объектов нет навигационные связи только в виде OrderId в OrderItem.

    Зачем оно мне? Я представляю связи между данными так как мне удобно.
    Re[41]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 08:37
    Оценка:
    Здравствуйте, gandjustas, Вы писали:


    G>Ну и в какой класс модели ты этот запрос засунешь?


    Это явно сервисный метод, OrderService, в модель засовываются только те методы которы изменяют данный класс или класс для которого данный является aggregation root. Для выборок — те методы для которых основным аргументом является this.

    G>Если вся программа на таких запросах, то rich не остается.


    А если не вся, то останется.

    G>Кроме того текстовые запросы таят те же проблемы, что и SQL.

    G>Напрмер у тебя в куче запросов надо выбирать ордеры в диапазоне дат, в твоем случае каждый запрос придется дублировать выделенный кусок кода, или заниматься конкатенацией строк (прощай читаемость).

    А альтернатива это linq? Ну так рекламируй linq, при чем тут модель?

    Z>>А теперь напиши линковский запрос в случае, когда твоя анемик модель действительно анемик. Т.е. у объектов нет навигационные связи только в виде OrderId в OrderItem.

    G>Зачем оно мне? Я представляю связи между данными так как мне удобно.

    Ну ты же заставляешь меня пихать всю логику в классы модели, а не туда где мне удобно, а?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[40]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 02.06.09 08:40
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Что-то я не понял, каким ОРМ тулом мы делаем подобные действия?

    Адекватный light-weight ORM должен это делать. См. напр. http://blogs.msdn.com/mattwar/archive/2009/01/22/building-a-linq-iqueryable-provider-part-xiii-iqtoolkit-v-0-13.aspx

    Z>При чем тут модель? Прямой запрос к базе на чистом сиквеле делается в любой модели и к выбраной модели не относится вообще.

    Чистый сиквел не типобезопасен и крайне труден в приготовлении. Нас не интересует возможность исполнить в СУБД какую-то строку. Нас интересует возможность собрать нужный запрос из нескольких фрагментов. Ну, а рич здесь проезжает мимо кассы потому, что в ней невозможно корректно обновить кэш при выполнении таких вот "непрозрачных" запросов.

    S>>Я просто всё еще жду жызненного примера, где рич порвёт анемик на тряпки. А то получается, что супергуру рич модели приводят в её защиту примеры, которые заведомо чудовищно неэффективны. Еще раз: не как пример "наивного" кода. А как пример того, что пишет компетентный девелопер в рич модели. Кому вы хотите продать рич модель? С такой-то аргументацией?


    Z>Я где-то утверждал, что она рвет анемик на тряпки?

    Нет. Но я же могу помечтать
    Z>Я утверждал, что она может стать проще для поддержки внесения изменений. Это сложно доказать.
    Это очень просто доказать — достаточно привести пример, и тупо посчитать количество изменяемых строчек.
    Z>Я в свою очередь жду пример сценария, а не императивного кода, где рич модель не может быть эффективна.
    Ну, я привёл пример сценария. Оказалось, что для него ричность модели использовать нельзя — потому что предложенное решение 1:1 такое же как анемик.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[42]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 08:51
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Если вся программа на таких запросах, то rich не остается.

    Z>А если не вся, то останется.
    А смысл? Зачем размазывать БЛ по классам с разными обязаннстями?

    G>>Кроме того текстовые запросы таят те же проблемы, что и SQL.

    G>>Напрмер у тебя в куче запросов надо выбирать ордеры в диапазоне дат, в твоем случае каждый запрос придется дублировать выделенный кусок кода, или заниматься конкатенацией строк (прощай читаемость).
    Z>А альтернатива это linq? Ну так рекламируй linq, при чем тут модель?

    Есть такой паттерн — QueryObject. Основное его преимущество в том что запросы можно строить динамически, накладывая произвольные проекции, соединения и грппировки.
    Linq — отличное средство для построения таких QueryObject_ов, в проверками типов во время компиляции и удобным маппингом результатов выборки.
    Тем не менее он не является необходимым. В Entity Framework есть текстовый eSQL, на котором построены Query Objects. eSQL вполне позволяет делать все тоже самое, даже немного больше (текстовая генерация иногда удобнее).

    Z>>>А теперь напиши линковский запрос в случае, когда твоя анемик модель действительно анемик. Т.е. у объектов нет навигационные связи только в виде OrderId в OrderItem.

    G>>Зачем оно мне? Я представляю связи между данными так как мне удобно.
    Z>Ну ты же заставляешь меня пихать всю логику в классы модели, а не туда где мне удобно, а?
    Я не заставляю. Если не пихать всю логику в классы модели, то rich не останется.
    Re[43]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 09:02
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Есть такой паттерн — QueryObject. Основное его преимущество в том что запросы можно строить динамически, накладывая произвольные проекции, соединения и грппировки.

    G>Linq — отличное средство для построения таких QueryObject_ов, в проверками типов во время компиляции и удобным маппингом результатов выборки.
    G>Тем не менее он не является необходимым. В Entity Framework есть текстовый eSQL, на котором построены Query Objects. eSQL вполне позволяет делать все тоже самое, даже немного больше (текстовая генерация иногда удобнее).

    Какое это отношение имеет к выбранной модели? Этот паттерн реализуется на уровне ОРМ, а не на уровне модели.

    Z>>>>А теперь напиши линковский запрос в случае, когда твоя анемик модель действительно анемик. Т.е. у объектов нет навигационные связи только в виде OrderId в OrderItem.

    G>>>Зачем оно мне? Я представляю связи между данными так как мне удобно.
    Z>>Ну ты же заставляешь меня пихать всю логику в классы модели, а не туда где мне удобно, а?
    G>Я не заставляю. Если не пихать всю логику в классы модели, то rich не останется.

    win again, сдаюсь.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[44]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 09:07
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Есть такой паттерн — QueryObject. Основное его преимущество в том что запросы можно строить динамически, накладывая произвольные проекции, соединения и грппировки.

    G>>Linq — отличное средство для построения таких QueryObject_ов, в проверками типов во время компиляции и удобным маппингом результатов выборки.
    G>>Тем не менее он не является необходимым. В Entity Framework есть текстовый eSQL, на котором построены Query Objects. eSQL вполне позволяет делать все тоже самое, даже немного больше (текстовая генерация иногда удобнее).

    Z>Какое это отношение имеет к выбранной модели? Этот паттерн реализуется на уровне ОРМ, а не на уровне модели.

    Самое прямое: использование запросов, а не работу с объектами, навигационный доступ и LL порождает совершенно другой дизайн кода.
    Именно об этом тут пытаются толковать.
    Кстати именно поэтому в спорах anemic vs rich там мало примеров приводят. Отличия обыно глобальные, которые невозможно рассмотреть в паре десятков строчек, а в простых случаях код выглядит одинаково.
    Re[45]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 09:18
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Самое прямое: использование запросов, а не работу с объектами, навигационный доступ и LL порождает совершенно другой дизайн кода.


    У тебя в модели и навигационный доступ и работа с объектами однако присутствует.

    G>Именно об этом тут пытаются толковать.

    G>Кстати именно поэтому в спорах anemic vs rich там мало примеров приводят. Отличия обыно глобальные, которые невозможно рассмотреть в паре десятков строчек, а в простых случаях код выглядит одинаково.

    Отличия как раз очень простые, пишут ли логику в классах модели. Может сама модель запрещать использовать себя не по правилам или для этого требуется дополнительный слой сервисов.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[46]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 09:28
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Самое прямое: использование запросов, а не работу с объектами, навигационный доступ и LL порождает совершенно другой дизайн кода.

    Z>У тебя в модели и навигационный доступ и работа с объектами однако присутствует.
    Это только только удобный способ выражать связи.
    Да и без LL навигационный доступ вполне может жить, только повсеместное его использование приводит к появлению монструозного кода.

    G>>Именно об этом тут пытаются толковать.

    G>>Кстати именно поэтому в спорах anemic vs rich там мало примеров приводят. Отличия обыно глобальные, которые невозможно рассмотреть в паре десятков строчек, а в простых случаях код выглядит одинаково.

    Z>Отличия как раз очень простые, пишут ли логику в классах модели. Может сама модель запрещать использовать себя не по правилам или для этого требуется дополнительный слой сервисов.

    Эти "простые отличия" тянут за собой множество непростых.
    Re[47]: Anemic Domain Model vs Rich Domain Model
    От: Ziaw Россия  
    Дата: 02.06.09 09:37
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Да и без LL навигационный доступ вполне может жить, только повсеместное его использование приводит к появлению монструозного кода.


    Именно. А LL лишь раздвигает рамки использования.

    G>>>Именно об этом тут пытаются толковать.

    G>>>Кстати именно поэтому в спорах anemic vs rich там мало примеров приводят. Отличия обыно глобальные, которые невозможно рассмотреть в паре десятков строчек, а в простых случаях код выглядит одинаково.

    Z>>Отличия как раз очень простые, пишут ли логику в классах модели. Может сама модель запрещать использовать себя не по правилам или для этого требуется дополнительный слой сервисов.

    G>Эти "простые отличия" тянут за собой множество непростых.

    Тянут только для того, чтобы принести некие (небесплатные) удобства, поскольку в анемик ты привык обходиться без них в рич тоже сможешь себе это позволить.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
    Re[48]: Anemic Domain Model vs Rich Domain Model
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 02.06.09 09:42
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>Здравствуйте, gandjustas, Вы писали:


    G>>Да и без LL навигационный доступ вполне может жить, только повсеместное его использование приводит к появлению монструозного кода.

    Z>Именно. А LL лишь раздвигает рамки использования.
    Рамки использования тула — да. Вообще тул должен предоставлять все возможности.
    Рамки применения навигационного доступа в anemic — нет.


    G>>>>Именно об этом тут пытаются толковать.

    G>>>>Кстати именно поэтому в спорах anemic vs rich там мало примеров приводят. Отличия обыно глобальные, которые невозможно рассмотреть в паре десятков строчек, а в простых случаях код выглядит одинаково.

    Z>>>Отличия как раз очень простые, пишут ли логику в классах модели. Может сама модель запрещать использовать себя не по правилам или для этого требуется дополнительный слой сервисов.

    G>>Эти "простые отличия" тянут за собой множество непростых.

    Z>Тянут только для того, чтобы принести некие (небесплатные) удобства, поскольку в анемик ты привык обходиться без них в рич тоже сможешь себе это позволить.

    Ок, пошли по N+1 кругу.
    Какие удобства имеются ввиду?
    Щас опять выяснится что удобств на самом деле и нет.
    Re[39]: Anemic Domain Model vs Rich Domain Model
    От: kvasya  
    Дата: 03.06.09 05:59
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>


    Не сочтите за наглость

    Можете посоветовать какой-нибудь пример реализации (opensource) Anemic модели?
    (Хочется посмотреть "как люди делают" и сравнить как делаю я)
    adm
    Re[40]: Anemic Domain Model vs Rich Domain Model
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 03.06.09 06:23
    Оценка: 2 (1)
    Здравствуйте, kvasya, Вы писали:
    K>Можете посоветовать какой-нибудь пример реализации (opensource) Anemic модели?
    K>(Хочется посмотреть "как люди делают" и сравнить как делаю я)
    BLToolkit?
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[20]: Anemic Domain Model vs Rich Domain Model
    От: Константин Л. Франция  
    Дата: 05.06.09 10:01
    Оценка: -1
    Здравствуйте, meowth, Вы писали:

    []

    M>Во-вторых, вы что-путаете. Что значит -- "с неполными данными"? В anemic как-то по-другому данные в коде оказываются, без запроса к БД?


    Дело в том, что в anemic к этому готовы и это нормально. А в риче вы либо получите 100 копий классов для одного и того же объекта предметной области, либо получите один, но написанный так, что он внутри должен учитывать все эти варианты неполноты данных. И в итоге будет так, что половина его методов просто не будут работать. Чтобы они работали нуден контекст, который в anemic всегда есть, тк вы знаете какие данные у вас есть, вы же их только что выбрали

    []
    Re[21]: Anemic Domain Model vs Rich Domain Model
    От: meowth  
    Дата: 05.06.09 11:30
    Оценка:
    Здравствуйте, Константин Л., Вы писали:

    КЛ>Здравствуйте, meowth, Вы писали:


    КЛ>[]


    M>>Во-вторых, вы что-путаете. Что значит -- "с неполными данными"? В anemic как-то по-другому данные в коде оказываются, без запроса к БД?


    КЛ>Дело в том, что в anemic к этому готовы и это нормально.

    К чему готовы-то? К тому, что данные попадают из БД в программу без запроса к БД?

    КЛ>А в риче вы либо получите 100 копий классов для одного и того же объекта предметной области, либо получите один, но написанный так, что он внутри должен учитывать все эти варианты неполноты данных. И в итоге будет так, что половина его методов просто не будут работать.

    ММ.. по-моему, вы сами счас придумали для rich model этот dirty hack, и начинаете укорять в нем rich. Попробуйте представить себе несколько окружений -- например, web-сессию, которая держит контекст на время обработки запроса.

    КЛ>Чтобы они работали нуден контекст, который в anemic всегда есть, тк вы знаете какие данные у вас есть, вы же их только что выбрали

    Не вижу, как это противоречит rich model или является ее недостатком или чем-то нереализуемым
    Re[22]: Anemic Domain Model vs Rich Domain Model
    От: Константин Л. Франция  
    Дата: 05.06.09 13:09
    Оценка:
    Здравствуйте, meowth, Вы писали:

    M>Здравствуйте, Константин Л., Вы писали:


    КЛ>>Здравствуйте, meowth, Вы писали:


    КЛ>>[]


    M>>>Во-вторых, вы что-путаете. Что значит -- "с неполными данными"? В anemic как-то по-другому данные в коде оказываются, без запроса к БД?


    КЛ>>Дело в том, что в anemic к этому готовы и это нормально.

    M>К чему готовы-то? К тому, что данные попадают из БД в программу без запроса к БД?

    К тому, что все что нам надо у нас есть, так как мы только что это взяли из базы.

    КЛ>>А в риче вы либо получите 100 копий классов для одного и того же объекта предметной области, либо получите один, но написанный так, что он внутри должен учитывать все эти варианты неполноты данных. И в итоге будет так, что половина его методов просто не будут работать.

    M>ММ.. по-моему, вы сами счас придумали для rich model этот dirty hack, и начинаете укорять в нем rich. Попробуйте представить себе несколько окружений -- например, web-сессию, которая держит контекст на время обработки запроса.

    Я придумал dirty hack? Ditry hack это иметь рич, но в большинстве случаев пользоваться срезами

    КЛ>>Чтобы они работали нуден контекст, который в anemic всегда есть, тк вы знаете какие данные у вас есть, вы же их только что выбрали

    M>Не вижу, как это противоречит rich model или является ее недостатком или чем-то нереализуемым

    Противоречит в том, что вы ничего не знаете о том, когда и какие данные вы взяли, чтобы сделать какую-то операцию
    Re[23]: Anemic Domain Model vs Rich Domain Model
    От: meowth  
    Дата: 05.06.09 16:17
    Оценка:
    Здравствуйте, Константин Л., Вы писали:

    ..[Многа букафф]..

    Не хочу я с вами спорить, извините Давайте будем априори считать, что в споре вы правы (*)
    Любой инструмент имеет границы применимости. Так же для любого инструмента имеются best practices, которые позволяют выступить ему во всей красе. Поэтому не стоит объединять недостатки модели и недостатки ОРМ, а также следует "включать мозг", как пишет gandjustats, когда пишется код -- естественно, никто не станет глубоко бродить по графу объектов, надеясь на LL.
    В чистом виде rich или anemic в моем опыте не применялся никогда (и не в моем тоже никогда не видел, кроме канонического ActiveRecord или Data Services), а, значит, проблемы одного обходились возможностями другого.
    Мне кажется, тут спорить не о чем. Если я не прав -- см. (*)
    Re[19]: Anemic Domain Model vs Rich Domain Model
    От: Лобанов Игорь  
    Дата: 06.06.09 15:34
    Оценка:
    Здравствуйте, koandrew, Вы писали:

    K>Здравствуйте, Лобанов Игорь, Вы писали:


    ЛИ>>Есть разные варианты:

    ЛИ>>1) Самый простой: кэш локален на каждом узле, согласованность обеспечивается синхронной инвалидацией;
    ЛИ>>2) Для кэша используются отдельные специализированные узлы. Это стандартное решение для создания высоконагруженных приложений на платформе LAMP+memcached;
    ЛИ>>3) Самый сложный: данные в кэше автоматически реплицируются и балансируются между узлами, что обеспечивает высокую надёжность. Ключевые слова: consistent hashing, in-memory data grid, cache partitioning. Сейчас (по крайней мере в JEE) такое умеют только дорогие проприетарные продукты типа Oracle Coherence, но на подходе и open source альтернативы.

    K>А вот теперь объясните мне пожалуйста, ради каких таких серьёзных и неоспоримых преимуществ стоит городить весь этот огород? Когда проблема элементарно решается reverse http proxy + proxy + клиентское кэширование — если мы говорим про веб (хотите узнать как — спросите у Синклера — он объяснит, если, конечно, его не заломает объяснять это в 1000001-й раз)...


    О решении какой проблемы Вы говорите?

    Я говорил о том, какими способами можно подружить кэш и кластеры.
    Re[11]: Anemic Domain Model vs Rich Domain Model
    От: koandrew Канада http://thingselectronic.blogspot.ca/
    Дата: 07.06.09 04:44
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Я знаю как системы кеширования запускать. Вопрос не в этом.

    G>Вопрос в том что фактически вместе с базой еще надо и навороченный кеш держать, чтобы rich мог работать на большом количестве данных.

    Что самое интересное, на высоких нагрузках в этот кэш уедет полбазы, а потом получается вообще патовая ситуация — одни и те же данные хранятся в двух разных местах К чему всё это?
    [КУ] оккупировала армия.
    Re[12]: Anemic Domain Model vs Rich Domain Model
    От: meowth  
    Дата: 07.06.09 08:31
    Оценка:
    Здравствуйте, koandrew, Вы писали:

    K>Здравствуйте, gandjustas, Вы писали:


    G>>Я знаю как системы кеширования запускать. Вопрос не в этом.

    G>>Вопрос в том что фактически вместе с базой еще надо и навороченный кеш держать, чтобы rich мог работать на большом количестве данных.

    K>Что самое интересное, на высоких нагрузках в этот кэш уедет полбазы, а потом получается вообще патовая ситуация — одни и те же данные хранятся в двух разных местах К чему всё это?


    Толсто
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.