AJD>В анемике я бы сделал иерархию валидаторов.
Поведение объекта обычно не заканчивается валидацией, и почти на каждое(считай метод или логическую группу методов) тебе придется писать иерархию.
Выход, но наверно не очень.
Здравствуйте, Аноним, Вы писали:
А>>>Я не агитирую за такой подход, но большинство web приложений и приложений работающих под большой нагрузкой (сотни транзакций в секунду) работают именно на TS. G>>stackoverflow работает под большой нагрузкой, но использует Linq2SQL G>>То что ты пишешь было правдой 15 лет назад. А>Посмотри на http://ormeter.net/ и увидишь разницу в материализации с ORM и без.
И что дальше? В Правильном(тм) приложении для типичной странички должно быть достаточно материализовать пару-тройку десятков объектов. Так что оверхед от ORM становится не таким серьёзным.
G>После этого оптимизируем запросы, чтобы не поднимать целые объекты из базы, а только необходимое. G>Для целей реюза кода делаем extract method, сходные методы группируем в классы. Получили anemic.
Еще пару взмахов кисти: убираем все в хранимку, вместо сущностей используем ViewModel и вот он TS.
Re[10]: Пара вопросов про анемик
От:
Аноним
Дата:
12.04.11 16:00
Оценка:
C>И что дальше? В Правильном(тм) приложении для типичной странички должно быть достаточно материализовать пару-тройку десятков объектов. Так что оверхед от ORM становится не таким серьёзным.
А зачем создавать кучу "не нужных" объектов. Т.к. из всех этих объектов все равно будут созданы DTO\ViewModel?
Я еще раз подчеркну, что я не сторонник хранения БЛ в процедурах. И тоже считаю, что расходы на создание объектов мизерны. Но вот пишут приложения на хранимках и TS.
Здравствуйте, Аноним, Вы писали:
AJD>>В анемике я бы сделал иерархию валидаторов. А>Поведение объекта обычно не заканчивается валидацией, и почти на каждое(считай метод или логическую группу методов) тебе придется писать иерархию. А>Выход, но наверно не очень.
Вот именно что "Поведение объекта обычно не заканчивается валидацией". И если все это поведение запихать в один ордер — тоже ничего хорошего не будет. Получится что-то типа: SuperOrder, SuperOrder2, SuperOrderNotSent, SimpleOrderWithPearlButton.
В анемике будет набор различных сервисов отвечающих за _конкретное_ действие. Как реализован валидатор через иерархию или ветвлением в методе — не столь существенно.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Здравствуйте, Аноним, Вы писали:
C>>И что дальше? В Правильном(тм) приложении для типичной странички должно быть достаточно материализовать пару-тройку десятков объектов. Так что оверхед от ORM становится не таким серьёзным. А>А зачем создавать кучу "не нужных" объектов. Т.к. из всех этих объектов все равно будут созданы DTO\ViewModel?
Для удобства. За тем же, зачем сейчас программы не пишут на ассемблере.
А>Я еще раз подчеркну, что я не сторонник хранения БЛ в процедурах. И тоже считаю, что расходы на создание объектов мизерны. Но вот пишут приложения на хранимках и TS.
Кто "пишут"? Поимённо, пожалуйста.
Хренимые процедуры сейчас явно уходят в legacy. Из топовых высоконагруженных сайтов архитектуру на хренимках вообще никто не строит (там вообще всё больше NoSQL). Даже Stackoverflow с классической реляционной БД использует LINQ.
Sapienti sat!
Re[12]: Пара вопросов про анемик
От:
Аноним
Дата:
12.04.11 16:56
Оценка:
А>>Я еще раз подчеркну, что я не сторонник хранения БЛ в процедурах. И тоже считаю, что расходы на создание объектов мизерны. Но вот пишут приложения на хранимках и TS. C>Кто "пишут"? Поимённо, пожалуйста.
C>Хренимые процедуры сейчас явно уходят в legacy. Из топовых высоконагруженных сайтов архитектуру на хренимках вообще никто не строит (там вообще всё больше NoSQL). Даже Stackoverflow с классической реляционной БД использует LINQ.
Здравствуйте, Аноним, Вы писали:
G>>Смотря какие процедуры, многие ORM вполне спокойно мапят CRUD для сущностей на процедуры. А>Ты не ответил на вопрос, что будет в коде, если весь БЛ в процедурах.
ответил: "что угодно". я видел реализацию active record, где все было на процедурах.
G>>Возможно, но я так не пишу. И не знаю никого кто так пишет. А>Я тебя удивлю, но очень многие.
Значит мне повезло, я с такими не знаком.
А>>>Я не агитирую за такой подход, но большинство web приложений и приложений работающих под большой нагрузкой (сотни транзакций в секунду) работают именно на TS. G>>stackoverflow работает под большой нагрузкой, но использует Linq2SQL G>>То что ты пишешь было правдой 15 лет назад. А>Посмотри на http://ormeter.net/ и увидишь разницу в материализации с ORM и без.
А что это должно показать?
G>>После этого оптимизируем запросы, чтобы не поднимать целые объекты из базы, а только необходимое. G>>Для целей реюза кода делаем extract method, сходные методы группируем в классы. Получили anemic. А>Еще пару взмахов кисти: убираем все в хранимку, вместо сущностей используем ViewModel и вот он TS.
И снова вспоминаем про меняющиеся бизнес-правила валидации. С реализацией в коде я без проблем с помощью IoC-контейнера будут подсовывать правила в сервис валидации. А что делать в хранимке? Править её каждый раз... нет уж, спасибо.
Здравствуйте, Аноним, Вы писали:
C>>Хренимые процедуры сейчас явно уходят в legacy. Из топовых высоконагруженных сайтов архитектуру на хренимках вообще никто не строит (там вообще всё больше NoSQL). Даже Stackoverflow с классической реляционной БД использует LINQ. А>Банки, биллинговые системы операторов связи.....
Ну оно и есть — legacy. Т.е. системы, которые развиваются часто ещё с 90-х годов.
Здравствуйте, Аноним, Вы писали:
AJD>>В анемике я бы сделал иерархию валидаторов. А>Поведение объекта обычно не заканчивается валидацией, и почти на каждое(считай метод или логическую группу методов) тебе придется писать иерархию. А>Выход, но наверно не очень.
Гораздо более плохой выход из ситуации множество иерархий объеденить в одну иерархию бизнес-объектов. Будет большущее нарушение SRP придется очень часто наследоваться или править классы.
Re[6]: Пара вопросов про анемик
От:
Аноним
Дата:
13.04.11 05:06
Оценка:
G>Гораздо более плохой выход из ситуации множество иерархий объеденить в одну иерархию бизнес-объектов. Будет большущее нарушение SRP придется очень часто наследоваться или править классы.
Давайте на примере. Условия таковы: заказ может быть оплачен только, если он одобрен менеджером, отгружен если оплачен и одобрен.
Rich:
class Order
{
bool _isApproved;
bool IsPayed{get;set;}
public bool CanPay
{
get
{
return !IsPayed && _isApproved;
}
}
public void Pay()
{
if(!CanPay())
{
// throw Ex
}
//что-то делаем
IsPayed=true;
}
public CanShip
{
get
{
return IsPayed && _isApproved;
}
}
}
DВ анемике, ты все равно создашь методы для проверки, + если добавится иерархия заказов в rich просто переопределяется поведение, в анемике ты все равно создашь иерархию классов, и как пишешь G> Гораздо более плохой выход из ситуации множество иерархий объеденить в одну иерархию бизнес-объектов.
создашь 2 параллельных иерархии зависимых друг от друга.
В этом примитивном примере можно конечно все сделать "красиво" и в анемике, но жизнь сложна. Скорее всего для каких-то заказов, возможно для определенных клиентов можно отгружать и не оплаченные заказы. Потребители твоих объектов (доменные сервисы) ни когда об этом не узнают. А вот в анемике начинаются инжектирования, появляются ветвления для одного атрибута(состояния) в разных методах и т.д. В результате ты создаешь намного больше кода, логика разбросана по куче классов и как результат нет гарантии, что в методе сервиса не забудут добавить поведение.
Re[14]: Пара вопросов про анемик
От:
Аноним
Дата:
13.04.11 05:32
Оценка:
C>Ну оно и есть — legacy. Т.е. системы, которые развиваются часто ещё с 90-х годов.
Да, но я видел несколько довольно крупных legacy проектов, которые переводили на процедуры в наше время.
И эти проекты были не форумами/блогами как Stackoverflow, БЛ там намного больше.
Re[4]: Пара вопросов про анемик
От:
Аноним
Дата:
13.04.11 05:59
Оценка:
Давайте подведем черту:
1. Я не агетирую за испльзование хранимок и логики в базе.
2. Очень много систем с БЛ в хранимках, со слоем Application Services который отдает не сущности домена, а ViewModel/DTO специально созданные под View, т.е. в таких системах отсутствие модель как таковая. И как такие системы называть Domain Model или TS? Если DM тогда объясните почему ее так зовут.
п.2 я написал не из любви к таким системам, их очент не просто сопровождать, особенно когда несколько баз, процедур в каждой сотни. Это почти Ад.
Я хочу лишь сказать, что TS существует и занимает довольно значительную долю.
3. А вот что выбрать Rich или Anemic это уже может зависить от сложности БЛ, опыта и т.д..... У обоих подходов есть и плюсы и минусы. Но анемик находится где-то между Rich и TS. Те же процедуры но уже в коде сервисов. Это все таки процедурный подход. Мне больше нравится Rich, я согласен что он сложнее для написания,но не сопровождения, и немного уступает в производительности особенно кода нужно получить список ассоциаций для объекта (в Rich это LazyLoad, а в анемике можно написать getItemsForCondition(int orderID, ... что-то, можно даже пэйджинг прикрутить)).
Здравствуйте, Аноним, Вы писали:
G>>Гораздо более плохой выход из ситуации множество иерархий объеденить в одну иерархию бизнес-объектов. Будет большущее нарушение SRP придется очень часто наследоваться или править классы. А>Давайте на примере. Условия таковы: заказ может быть оплачен только, если он одобрен менеджером, отгружен если оплачен и одобрен. А>Rich:
Говнокод детектед. Как отобразить готовые к отгрузке заказы или ожидающие утверждения? Икапсуляция резко идет лесом.
Кроме того абсолютно непонятно к чему этот код, думаешь в anemic не получится родить аналогичный функционал с меньшим количеством строк?
А>DВ анемике, ты все равно создашь методы для проверки, + если добавится иерархия заказов в rich просто переопределяется поведение, в анемике ты все равно создашь иерархию классов, и как пишешь
Иерархию заказов ты придумал, в anemic она не появится, незачем.
G>> Гораздо более плохой выход из ситуации множество иерархий объеденить в одну иерархию бизнес-объектов. А>создашь 2 параллельных иерархии зависимых друг от друга.
Это еще хуже чем одна толстая иерархия, потому что больше неявных связей. Формально SRP может и выполняется, но сильно нарушается OCP и дико растут метрики связности классов.
А>В этом примитивном примере можно конечно все сделать "красиво" и в анемике, но жизнь сложна.
То что сложно делается в anemic в rich получается еще сложнее. Обратных примеров я покачто не видел.
А>Скорее всего для каких-то заказов, возможно для определенных клиентов можно отгружать и не оплаченные заказы. Потребители твоих объектов (доменные сервисы) ни когда об этом не узнают. А вот в анемике начинаются инжектирования, появляются ветвления для одного атрибута(состояния) в разных методах и т.д. В результате ты создаешь намного больше кода, логика разбросана по куче классов и как результат нет гарантии, что в методе сервиса не забудут добавить поведение.
Ты правда считаешь что один-два if создает больше кода, чем наследование класса + переопределение методов + настройка маппинга для создание объекта нужного класса + создание параллельной иерархии для валидаторов или ещечегонить?
Здравствуйте, Аноним, Вы писали:
А>Давайте подведем черту: А>1. Я не агетирую за испльзование хранимок и логики в базе.
Тогда к чему были посты?
А>2. Очень много систем с БЛ в хранимках, со слоем Application Services который отдает не сущности домена, а ViewModel/DTO специально созданные под View, т.е. в таких системах отсутствие модель как таковая.
Это сильно устаревшие системы. Многие из них зародились до 2000 года. Сейчас использовать ХП — анахронизм.
А>И как такие системы называть Domain Model или TS? Если DM тогда объясните почему ее так зовут.
Как хочешь, так и называй, мне то что?
90% ХП, которые я видел — обычный CRUD и прекрасно мапятся с помощью ORM, а там хоть DM, хоть acive record.
А>Я хочу лишь сказать, что TS существует и занимает довольно значительную долю.
TS в каком виде? Как фаулер описал? Я такого вообще нигде не видел.
Если называть TS когда хранимки вызываются из button_click, то возможно ты и прав.
А>3. А вот что выбрать Rich или Anemic это уже может зависить от сложности БЛ, опыта и т.д..... У обоих подходов есть и плюсы и минусы.
У Rich скорее минусы, чем полюсы.
А>Но анемик находится где-то между Rich и TS.
По какой шкале? Какое отношение порядка ты используешь?
А>Те же процедуры но уже в коде сервисов.
Вообще-то нет, современные языки гораздо богаче диалектов SQL.
А>Это все таки процедурный подход.
Я бы сказал "функциональный", ибо не используя композицию функций не добиться положительных результатов.
А>Мне больше нравится Rich, я согласен что он сложнее для написания,но не сопровождения, и немного уступает в производительности особенно кода нужно получить список ассоциаций для объекта (в Rich это LazyLoad, а в анемике можно написать getItemsForCondition(int orderID, ... что-то, можно даже пэйджинг прикрутить)).
Самая большая проблема rich, что его недостатки не лечатся вообще никак. Если пытаться избавиться от недостатков, то получается anemic. Собственно я и говорил что хороший rich — это anemic. Даже тебе показал преобразование, которое дает решению большую гибкость и простор для оптимизации.
Здравствуйте, Аноним, Вы писали:
C>>Ну оно и есть — legacy. Т.е. системы, которые развиваются часто ещё с 90-х годов. А>Да, но я видел несколько довольно крупных legacy проектов, которые переводили на процедуры в наше время. А>И эти проекты были не форумами/блогами как Stackoverflow, БЛ там намного больше.
Думаешь в stackoverflow мало бл? Сильно ты заблуждаешься. Только stackoverflow держит бешеные нагрузки, а этот "legacy софт на ХП" падает при смешном количестве пользователей.
Re[8]: Пара вопросов про анемик
От:
Аноним
Дата:
13.04.11 08:12
Оценка:
Здравствуйте, gandjustas, Вы писали:
G>Говнокод детектед. Как отобразить готовые к отгрузке заказы или ожидающие утверждения? Икапсуляция резко идет лесом.
Нет,если не знаешь как такие вещи реализуются читаем (например http://www.kitchaiyong.net/2009/10/repository-specification-unit-of-work.html) и понимает как это делается. Атрибуты сущности можно сделать публичными. Я не писал в переведенном примере идеальный код, а хотел показать только основные моменты.
G>Кроме того абсолютно непонятно к чему этот код, думаешь в anemic не получится родить аналогичный функционал с меньшим количеством строк?
Пример.
А>>DВ анемике, ты все равно создашь методы для проверки, + если добавится иерархия заказов в rich просто переопределяется поведение, в анемике ты все равно создашь иерархию классов, и как пишешь G>Иерархию заказов ты придумал, в anemic она не появится, незачем.
Ну в заказах может и надуманна иерархия, но в реальных системах такого очень много.
G>>> Гораздо более плохой выход из ситуации множество иерархий объеденить в одну иерархию бизнес-объектов. А>>создашь 2 параллельных иерархии зависимых друг от друга. G>Это еще хуже чем одна толстая иерархия, потому что больше неявных связей. Формально SRP может и выполняется, но сильно нарушается OCP и дико растут метрики связности классов.
Так приведи пример реализации. И в твоем случае если требования для поведения Pay меняются ты нарушишь OCP.
А>>В этом примитивном примере можно конечно все сделать "красиво" и в анемике, но жизнь сложна. G>То что сложно делается в anemic в rich получается еще сложнее. Обратных примеров я покачто не видел.
Я не говорю что Rich легче и меньше кода пишется, возможно поэтому его и меньше используют. Знаний нужно больше.
А>>Скорее всего для каких-то заказов, возможно для определенных клиентов можно отгружать и не оплаченные заказы. Потребители твоих объектов (доменные сервисы) ни когда об этом не узнают. А вот в анемике начинаются инжектирования, появляются ветвления для одного атрибута(состояния) в разных методах и т.д. В результате ты создаешь намного больше кода, логика разбросана по куче классов и как результат нет гарантии, что в методе сервиса не забудут добавить поведение. G> G>Ты правда считаешь что один-два if создает больше кода, чем наследование класса + переопределение методов + настройка маппинга для создание объекта нужного класса + создание параллельной иерархии для валидаторов или ещечегонить?
Ну если в системах которые ты пишешь возможен только 2 поведения тебе везет! Обычно все намного сложней.
Давай примеры кода. Рассуждать можно много.
Здравствуйте, gandjustas, Вы писали:
G>Думаешь в stackoverflow мало бл? Сильно ты заблуждаешься. Только stackoverflow держит бешеные нагрузки, а этот "legacy софт на ХП" падает при смешном количестве пользователей.
Все сильно зависит от типа нагрузки. Очень сильно сомневаюсь, что у stackoverflow на каждый чих производится транзакционная вставка и обновление кучи таблиц, как это происходит в банковском софте.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Здравствуйте, AndrewJD, Вы писали:
AJD>Здравствуйте, gandjustas, Вы писали:
G>>Думаешь в stackoverflow мало бл? Сильно ты заблуждаешься. Только stackoverflow держит бешеные нагрузки, а этот "legacy софт на ХП" падает при смешном количестве пользователей.
AJD>Все сильно зависит от типа нагрузки. Очень сильно сомневаюсь, что у stackoverflow на каждый чих производится транзакционная вставка и обновление кучи таблиц, как это происходит в банковском софте.
Может и не на каждый чих, но у stakoverflow почти каждую секунду появляются вопросы\ответы и оценки, а если весь stakexchange рассмотреть, то там гораздо больше выйдет. некоторый "Банковский софт" умудряется тормозить при совершенно банальных операциях, вроде просмотра форм, двумя-тремя пользователями раз в минуту.