роль ООП при работе с данными
От: QrystaL Украина  
Дата: 21.10.08 04:37
Оценка:
Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686

Кто что скажет?

21.10.08 13:06: Перенесено модератором из '.NET' — TK
Re: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.10.08 04:59
Оценка: :)))
Здравствуйте, QrystaL, Вы писали:

QL>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686

QL>Кто что скажет?
Статья правильная, хоть и написана несколько сумбурно. Больше похоже на стенограмму устного выступления, чем на журнальную статью. Ну, так это ж блог — "концерт в халате на лестничной клетке"
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: роль ООП при работе с данными
От: Аноним  
Дата: 21.10.08 08:57
Оценка:
Очень интересная статья, задевает очень интересные темы.

Мне кажется, все зависит от того, что является отправной точкой. Если это Данные (БД), если данные нужно лишь представить пользователю, сортануть, фильтрануть и т.п., то конечно стройная модель вне конкуренции. Но если данные подлежать сложной обработке, расчетам, тут без объектов тяжело обойтись, сложную BL лучше всего в жирную модель паковать.

Как вообще может выглядеть архитекрура приложения в стройной модели. Как происходить расчленение на слои, какие они? Кинтье ссылки, тема очень интересная
Re[2]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.10.08 09:58
Оценка: 14 (3) +5
Здравствуйте, <Аноним>, Вы писали:

А>Очень интересная статья, задевает очень интересные темы.


А>Мне кажется, все зависит от того, что является отправной точкой. Если это Данные (БД), если данные нужно лишь представить пользователю, сортануть, фильтрануть и т.п., то конечно стройная модель вне конкуренции. Но если данные подлежать сложной обработке, расчетам, тут без объектов тяжело обойтись, сложную BL лучше всего в жирную модель паковать.

В одной фразе сделано два несвязанных утверждения. Одно из них может быть верным, второе — крайне сомнительно.
Совершенно непонятно, чем мотивируется всовывание "сложной обработки" в жырную модель.
Поясняю на пальцах: вот есть у нас данные по продажам. Чек из магазина видели? "Сыр плав янт 0.406 132.70" и так далее? Он, понятное дело, печатается с компьютера, и всё это хранится в центральной БД.
Вот такой муйни — десятки миллионов строк. Всё повязано с датами, кредитными картами, и прочим. Аналитики годами придумывают алгоритмы сложной обработки, которые пытаются вытащить их этих кассовых чеков что-то полезное; типа трендов и корреляций.

Вниммание, вопрос: как назвать метод для построения возрастного тренда потребления товаров алкогольной группы, который мы вставим в класс OrderItem? А? Или этот метод будет в классе Order?
А ведь именно это и есть жирная модель.

А>Как вообще может выглядеть архитекрура приложения в стройной модели. Как происходить расчленение на слои, какие они?

Главным образом слой "алгоритмов" отделен от слоя данных, над которыми алгоритмы оперируют. При этом сами алгоритмы запросто могут быть полиморфными, параметризовываться друг другом и т.п. — то есть ООП на полную катушку. Не надо только их засовывать в данные.

Жирная модель в её крайнем проявлении — это вставка метода "взятие интеграла" в класс "Число". С перегрузками в классах "Целое число" и "Комплексное число".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: роль ООП при работе с данными
От: Mmmaloy Германия  
Дата: 21.10.08 10:37
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, <Аноним>, Вы писали:


А>>Очень интересная статья, задевает очень интересные темы.


А>>Мне кажется, все зависит от того, что является отправной точкой. Если это Данные (БД), если данные нужно лишь представить пользователю, сортануть, фильтрануть и т.п., то конечно стройная модель вне конкуренции. Но если данные подлежать сложной обработке, расчетам, тут без объектов тяжело обойтись, сложную BL лучше всего в жирную модель паковать.

S>В одной фразе сделано два несвязанных утверждения. Одно из них может быть верным, второе — крайне сомнительно.
S>Совершенно непонятно, чем мотивируется всовывание "сложной обработки" в жырную модель.
S>Поясняю на пальцах: вот есть у нас данные по продажам. Чек из магазина видели? "Сыр плав янт 0.406 132.70" и так далее? Он, понятное дело, печатается с компьютера, и всё это хранится в центральной БД.
S>Вот такой муйни — десятки миллионов строк. Всё повязано с датами, кредитными картами, и прочим. Аналитики годами придумывают алгоритмы сложной обработки, которые пытаются вытащить их этих кассовых чеков что-то полезное; типа трендов и корреляций.

S>Вниммание, вопрос: как назвать метод для построения возрастного тренда потребления товаров алкогольной группы, который мы вставим в класс OrderItem? А? Или этот метод будет в классе Order?

S>А ведь именно это и есть жирная модель.

А>>Как вообще может выглядеть архитекрура приложения в стройной модели. Как происходить расчленение на слои, какие они?

S>Главным образом слой "алгоритмов" отделен от слоя данных, над которыми алгоритмы оперируют. При этом сами алгоритмы запросто могут быть полиморфными, параметризовываться друг другом и т.п. — то есть ООП на полную катушку. Не надо только их засовывать в данные.

S>Жирная модель в её крайнем проявлении — это вставка метода "взятие интеграла" в класс "Число". С перегрузками в классах "Целое число" и "Комплексное число".


Ну и какой толк отделения данных от алгоритмов, если любое изменение данных должна по идее повлечь изменение алгоритмов. Но опять же это все мое мнение, человека не имевшего опыта работы со стройной моделью. Хотелось бы посмотреть на код, какой-то проект, что бы сравниить, где данные от алгритмов отделены. Есть ссылки
Re[4]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.10.08 10:56
Оценка: +1
Здравствуйте, Mmmaloy, Вы писали:

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

Всё как раз наоборот.
Во-первых, как это вы собрались внести "любое изменение" в данные о продажах сети Wallmart с 1975 года?

Во-вторых, то, что вы называете "изменения данных", совершенно несущественно для большинства алгоритмов.

Ну вот, например, стали вы хранить не только ФИО менеджера, но и её девичью фамилию в уместных случаях.
Что, это как-то повлияет на алгоритм распределения заказов по менеджерам?

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

Анемичной модели всё равно, что там происходит с данными, которые ей не интересны. Мы по-прежнему можем скармливать в алгоритм объекты со старой структурой, благо стоимость поддержки каждого класса такой модели близка к нулю. Это провоцирует иметь достаточное разнообразие легковесных классов, вместо повторного использования небольшого набора тяжеловесных.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: роль ООП при работе с данными
От: Mmmaloy Германия  
Дата: 21.10.08 11:10
Оценка:
S>Всё как раз наоборот.
S>Во-первых, как это вы собрались внести "любое изменение" в данные о продажах сети Wallmart с 1975 года?

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


S>Ну вот, например, стали вы хранить не только ФИО менеджера, но и её девичью фамилию в уместных случаях.

S>Что, это как-то повлияет на алгоритм распределения заказов по менеджерам?

Сейчас оспорю: ну, допустим, добавился какой-то там коэффициент, а наши алгоритмы забыли его применить. Результат — неверные расчеты. Мой аргумент — лишь для того что бы показать, что это может быть не всегда это хорошо. . (Зы: дискусию можете на эту тему не развивать, я хорошо понимаю указанные вами преимещества )

S>Да, в жырной модели вам придется напрячься как следует. Такое изменение — это форс-мажор, требующий немедленной перекомпиляции и замены всех клиентов, а в особо тяжких случаях умственных расстройств (см. тж. CRUD) — еще и апдейт большого ассортимента хранимых процедур.


Ну для этого есть хранимы процедуры

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


Вообще интересует архитектруа. Вообще меня интересует архитектура, получается, если мы используем только легкие классы, то слой Бизнес логики уже не предоставляет интереса, и последующим классом сервиса, который этот слой обрабатывает и отдает результаты наверх. Все выборки и обработки можно делать в предствениях. Или? Хочу живой пример , проект
Re: роль ООП при работе с данными
От: Volgaboatman  
Дата: 21.10.08 11:25
Оценка: +1
Здравствуйте, QrystaL, Вы писали:

QL>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686


QL>Кто что скажет?


Немного сумбурная. Больше всего повеселило, что сначала NHibernate представляется как монстр, который может использоваться только "жирную модель", а EF — провоцирует работать с данными "Стройном" стиле. Потом следует в общем-то правильные рассуждения, что "стройный" стиль удобнее. Основанные исключительно на примерах запросов к базе (про CRUD операции ничего нет). А потом делается вывод, что раз "жирный" стиль — это попсня и отстой — то отсутсвие поддрежки LazyLoad в EF это хорошо. Хотя по моему несколько не верная логическая цепочка.

Как всегдя подпись забыл. Я.
... << RSDN@Home 1.2.0 alpha 4 rev. 1061>>
Re[6]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.10.08 11:29
Оценка:
Здравствуйте, Mmmaloy, Вы писали:

M>Сейчас оспорю: ну, допустим, добавился какой-то там коэффициент, а наши алгоритмы забыли его применить.

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

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

Давайте рассмотрим более реалистичный пример: начальник отдела ценообразования решил разрешать менеджерам указывать скидку на конкретные позиции на свое усмотрение. При этом можно делать разную скидку разным позициям.
В толстой модели это дупа: расчет цены позиции вшит в класс OrderItem, теперь его надо поменять. В классе Order у нас был расчет скидки на весь заказ, на основе данных клиента, его нужно не забыть выкинуть, иначе скидка посчитается два раза. Куча кода, завязанного на то, что в позции хранится сумма без скидки, поползет.

В анемичной модели у нас код расчета скидок отделен от кода представления заказов. Мы точно знаем, где и что нужно менять. Более того, мы можем полиморфно выбирать алгоритм расчета скидок в зависимости от, к примеру, даты создания заказа. Чтобы задним числом ничего не пересчитывать.

Главное — не думать об этом в терминах "о, мы добавили в класс OrderItem коэффициент скидки, что теперь делать?".

M>Ну для этого есть хранимы процедуры

Для чего? Для того, чтобы расширение базы не сводилось к alter table add column, а еще и требовалось пересоздать все процедуры типа Create_Manager?

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

У меня сбой парсинга набора слов. Что хотелось узнать?
M>Все выборки и обработки можно делать в предствениях. Или? Хочу живой пример , проект
У меня — нету живого примера. Я проектированием Enterprize приложений давно уже не занимаюсь. Может, IB что подкинет.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 21.10.08 12:06
Оценка: 3 (1)
Здравствуйте, Sinclair, Вы писали:

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

Ну так и писалось. Просто хотелось все тезисы того флейма в одно место сложить.. =)
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[2]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 21.10.08 12:06
Оценка:
Здравствуйте, Volgaboatman, Вы писали:

V>Больше всего повеселило, что сначала NHibernate представляется как монстр, который может использоваться только "жирную модель", а EF — провоцирует работать с данными "Стройном" стиле.

Блин, ну не там такого. Оно, конечно, сумбурно, но конкретно про гибернейт в этом сумбуре нет ни слова.
Там есть "мнение авторов NHibernate" (c). Авторы NH выступают за жирный стиль, и обвиняют EF в провокации стройного. Все.
Там написано только это и ничего более. Еще раз повторюсь, я не настоящий сварщик и мотоцикл не мой, это позиция авторов NH, на которую я описаюсь в своих рассуждениях.

V>Хотя по моему несколько не верная логическая цепочка.

Там совсем другая логическая цепочка.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[2]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 21.10.08 12:09
Оценка:
Здравствуйте, Volgaboatman, Вы писали:

V> Больше всего повеселило, что сначала NHibernate представляется как монстр, который может использоваться только "жирную модель", а EF — провоцирует работать с данными "Стройном" стиле.

Специально цитата из комментариев, еще раз:
На всякий случай, еще раз проясню свою позицию, чтобы она дошла до самых отдаленных уголков мозга внимательных читателей...
Я специально старался нигде не затронуть ни NH, ни любой другой ORM инструмент, чтобы не ввязываться в бесполезные религиозные споры. Я лишь констатировал тот факт, что _разработички_ NH являются сторонниками "жирной" модели. О чем недвусмысленно заявлено в их манифесте: "The Entity Framework encourages the Anemic Domain Model anti-pattern by discouraging the inclusion of business logic in the entity classes".
В отличии от них, я считаю антипаттерном именно Rich модель, а Anemic, как раз очень правильным паттерном. Почему я так считаю, я и описал в данной статье.
Я вполне допускаю, что мнение разработчиков NH может не совпадать с возможностями инструмента, который у них получился. Возможности NH — совершенно отдельный вопрос, который на данный момент мне вообще мало интересен.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[3]: роль ООП при работе с данными
От: IT Россия linq2db.com
Дата: 21.10.08 14:04
Оценка: +1 :))
Здравствуйте, IB, Вы писали:

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

IB>Ну так и писалось. Просто хотелось все тезисы того флейма в одно место сложить.. =)

То-то я и думаю, где-то я это всё уже читал. Хотел даже автора в плагиатстве упрекнуть
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Re: роль ООП при работе с данными
От: IT Россия linq2db.com
Дата: 21.10.08 14:33
Оценка: +1
Здравствуйте, QrystaL, Вы писали:

QL>Кто что скажет?


Жаль, что в результате всё опять свелось к выяснению какой подход более объектно-ориентированный. По мне, так это похоже на высянение какой инструмент более молоток — отвертка или плоскогубцы.
Неясность изложения обычно происходит от путаницы в мыслях.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: роль ООП при работе с данными
От: Mmmaloy Германия  
Дата: 21.10.08 14:59
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

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

В моей реальности тоже алгоритм и его изменения первичны. Но у меня есть шеф. ТЧК. Его эти алгоритмы не интересуют, или точнее стоят на втором месте. В первую очередь его интересуют данные, которые лежат в базе. Данные которые там лежат — это сердце,от них идет вся остальная пляска. Обработка данных довольно сложная. И ее предствление может меняться (в принципе не новость). В его интресах реализовать все по максимуму быстро и просто, задействовав лишь средства представляемые языком (c#) и его стандартными библиотеками. При этом он застявляет меня отказаться от объектов, другими словами от жирной модели (которую я, не так давно-то освоил, но она меня удовлетворяет, вроде бы все складно получается, да и с объектами мне как-то проще работать). Взамен предлагает вытаскивать данные в DataSet, из него XML-представление DataSet и с помощью xslt проецировать данные в новые Xml, которые представляются (юзер интрефейс). Как в таком приложении распределить наилучшим способом слои, логику ума неприложу. Ведь данные нужно еще редактировать, валидировать. А тут эта статься подвернулась, ну думаю "АГА! Вот кажется то что впишется и в мое понятие и понятие начальника (его понятие исключает ООП)". В принципе, насколько я его понял, его интересует как я понимаю, его то и интересует стройная модель, но как к этому подойти незнаю.

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


S>Давайте рассмотрим более реалистичный пример: начальник отдела ценообразования решил разрешать менеджерам указывать скидку на конкретные позиции на свое усмотрение. При этом можно делать разную скидку разным позициям.

S>В толстой модели это дупа: расчет цены позиции вшит в класс OrderItem, теперь его надо поменять. В классе Order у нас был расчет скидки на весь заказ, на основе данных клиента, его нужно не забыть выкинуть, иначе скидка посчитается два раза. Куча кода, завязанного на то, что в позции хранится сумма без скидки, поползет.

Здесь опять куча утверждений, я прекрасно обхожусь с объектами и данными в них, и не думаю что для меня это было бы проблеммой. Хотя кто его знает, надо сравнивать.

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


S>Главное — не думать об этом в терминах "о, мы добавили в класс OrderItem коэффициент скидки, что теперь делать?".


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

S>У меня сбой парсинга набора слов. Что хотелось узнать?
M>>Все выборки и обработки можно делать в предствениях. Или? Хочу живой пример , проект
S>У меня — нету живого примера. Я проектированием Enterprize приложений давно уже не занимаюсь. Может, IB что подкинет.

Извиняюсь за изложение мыслей, фактор времени давил, не сформировал до конца. Попробую еще раз. Было указанно о полезности легковесных классов, которые содержат только ту логику (алгоритмы), которая нужна, данные здесь в стороне. Было интересно какое место эти алгоритмы займут в архитектуре приложения.

Еще раз ко всем — вот бы живой проектик для изучения.
Re[8]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.10.08 15:48
Оценка: 7 (2) +1
Здравствуйте, Mmmaloy, Вы писали:

M>В моей реальности тоже алгоритм и его изменения первичны. Но у меня есть шеф. ТЧК. Его эти алгоритмы не интересуют, или точнее стоят на втором месте.

Вы просто плохо понимаете, о чем вам толкует шеф.
M>В первую очередь его интересуют данные, которые лежат в базе. Данные которые там лежат — это сердце,от них идет вся остальная пляска.
Совершенно верно. И я слабо себе представляю, по какой причине структура этого сердца может самопроизвольно изменится. Да еще и так, что алгоритмы потребуется "подгонять" под нее.
M>Обработка данных довольно сложная. И ее предствление может меняться (в принципе не новость). В его интресах реализовать все по максимуму быстро и просто, задействовав лишь средства представляемые языком (c#) и его стандартными библиотеками. При этом он застявляет меня отказаться от объектов, другими словами от жирной модели (которую я, не так давно-то освоил, но она меня удовлетворяет, вроде бы все складно получается, да и с объектами мне как-то проще работать).
По-прежнему через запятую перечисляются совершенно ортогональные вещи. Работайте с объектами — кто вам запрещает? DataSet — это объект. XsltTransform — тоже объект. В чем проблема?

M>Взамен предлагает вытаскивать данные в DataSet, из него XML-представление DataSet и с помощью xslt проецировать данные в новые Xml, которые представляются (юзер интрефейс).

Это, конечно, не единственный способ построить MVP архитектуру, но в принципе вполне жизнеспособный. Поясняю: в этом подходе данные достаются из SQL сервера за один (1) прием. Есть гарантия того, что никакая ленивая зараза не потащит какой-то хвост из базы в момент, когда уже Render поехал. Далее, нет никакого кэша объектов, который живет своей жизнью, жрет память и требует синхронизации. Всё, мы датасет забрали, теперь можно отпустить SQL сервер заниматься другой полезной работой. Импульсный режим для серверов — это самый сенокос.

Теперь у нас, значит, поехала трансформация. В чем начальник прав? С тем, что редкий databound контрол в aspx сравнится по скорострельности отплевывания форматированного аутпута со старым добрым откомпилированным XSLT. Я надеюсь, все в курсе, что текстовый XSLT сначала парсится, потом по нему генерируется MSIL код, который затем обрабатывается джитом, и в итоге мы имеем самый что ни на есть нативный код, который шарашит по твоему XML как казак по степи?

M>Как в таком приложении распределить наилучшим способом слои, логику ума неприложу.

Ну, всё зависит от того, какие именно трансформации надо делать. Если данные подготовлены в приемлемом виде, то, скорее всего, двухстадийной конверсии вполне хватит. Слой номер 1 будет отвечать за перекладывание данных в представление, эквивалентное по структуре целевому layout, а слой номер 2 будет отвечать за применение визуальных стилей и вообще конверсию каркаса layout в конечный HTML.

M>Ведь данные нужно еще редактировать, валидировать.

Я так понял, что редактирование данных в вашем случае — редкая и малонужная экзотика. Сложными являются алгоритмы обработки, так? Если не так, то нужно понимать, что
а) вводиться должны не те данные, которые удобно обрабатывать и хранить, а те, которые удобно вводить. Нет ничего хуже для UI, чем generic grid и generic edit form. Введенные данные должны как-то обработаться и лечь в базу.
б) валидацию данных крайне вредно проводить в классах самих данных. Дело в том, что правила валидации почти никогда не бывают настолько жесткими, как модель ООП. Это скорее рекомендации, или пожелания. Вам сказали, что в почтовом индексе могут быть только цифры? Забудьте, Австралия и Англия используют буквы с цифрами. Если вы держите код валидации отдельно от данных, вам чинить такие проблемы легко и приятно. Более того, вам не нужен экземпляр класса "Покупатель" для того, чтобы проверить ввденный индекс на корректность. За это отвечает какой-то ZipFieldValidator, который никак не связан с domain model.

M>А тут эта статься подвернулась, ну думаю "АГА! Вот кажется то что впишется и в мое понятие и понятие начальника (его понятие исключает ООП)". В принципе, насколько я его понял, его интересует как я понимаю, его то и интересует стройная модель, но как к этому подойти незнаю.


SM>Здесь опять куча утверждений, я прекрасно обхожусь с объектами и данными в них,

Мы говорим не о данных в объектах, а о логике в этих объектах.

M>Извиняюсь за изложение мыслей, фактор времени давил, не сформировал до конца. Попробую еще раз. Было указанно о полезности легковесных классов, которые содержат только ту логику (алгоритмы), которая нужна, данные здесь в стороне.

Еще раз, на пальцах: легковесные классы в анемичной модели никакой логики не содержат. Это просто контейнеры для данных.
M>Было интересно какое место эти алгоритмы займут в архитектуре приложения.
"Эти" — это какие? Поймите, ООП — это про поведение. У данных никакого поведения нет. Это не "заказ" выбирает себе "менеджера", и не "менеджер" захватывает себе заказ. Поведение есть у системы: OrderProcessingService назначает менеджера для нового заказа. Причем он запросто при этом может пользоваться ManagerSelectionService для того, чтобы абстрагироваться от алгоритма поиска подходящего менеджера.
Вы про эти алгоритмы говорите?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: роль ООП при работе с данными
От: Aikin Беларусь kavaleu.ru
Дата: 22.10.08 07:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вниммание, вопрос: как назвать метод для построения возрастного тренда потребления товаров алкогольной группы, который мы вставим в класс OrderItem? А? Или этот метод будет в классе Order?

S>А ведь именно это и есть жирная модель.
Антон, это жирная модель наивысшей степени ожирения.

Вот Иван противопоставляет стройную модель жирной: чистые контейнеры данных -- супер пупер навороченым "сам-самычам" (все делают сами).
Опять спор белого и черного? А как же светло-черный, темно-белый, серый наконец? Существует же огромное количество промежуточных цветов.
Зачем все возводить в абсолют? Если стройная, то аннорексия, если жирная, то высшая степень ожирения




Я не буду озвучивать свою текущую позицию (кроме того, что она является светло-светло-черной (anemic-anemic-rich model)). Ибо знаю, что сейчас пойдет спор на много постов, в итоге которого каждый останется при своем мнении либо же все придем к единому, но разобраться в том "как это было" будет невозможно.


Давайте развернем дискуссию. Начнем с конкретной реализации, а только потом займемся идеями лежащими в основе.

Поэтому остановимся на конкретном примере (из моего текущего проекта):
Система управления проектами. Ключевая сущность -- Проект. На проекте находятся люди (Participants). У проекта есть проджект лид (PL) и человек отвечающий за текущий этап работ 'Assigned To' (AT).

Бизнесс требования (те что есть у нас сейчас):
1) AT и PL может быть назначен любой пользователь системы.
2) При изменении AT либо PL на другого пользователья, старый должен оставаться в проекте.
3) AT и PL не могут быть удалены из пользователей проекта.


Как реализовывать эти требования в Rich модели я знаю. Работать с полученным классом будет удобно. А вот как сделать то же самое (сохранив удобство) в анемичном стиле... ума не приложу.


СУВ, Андрей

P.S. Еще желательно держать в уме требование ведения истории изменений в проекте. Как только разберемся с AT/PL рассмотрим его (ибо я совсем не понимаю как его удобно реализовать в анемичной модели).
Re[9]: роль ООП при работе с данными
От: Mmmaloy Германия  
Дата: 22.10.08 08:30
Оценка:
Спрева слова благодарности, что теряешь со мной время.

M>>Обработка данных довольно сложная. И ее предствление может меняться (в принципе не новость). В его интресах реализовать все по максимуму быстро и просто, задействовав лишь средства представляемые языком (c#) и его стандартными библиотеками. При этом он застявляет меня отказаться от объектов, другими словами от жирной модели (которую я, не так давно-то освоил, но она меня удовлетворяет, вроде бы все складно получается, да и с объектами мне как-то проще работать).

S>По-прежнему через запятую перечисляются совершенно ортогональные вещи. Работайте с объектами — кто вам запрещает? DataSet — это объект. XsltTransform — тоже объект. В чем проблема?

Запрещается наследоваться что бы расширить функционал, запрещается агрегация что бы скрыть лишние свойсвтва объектов, все должно быть по возможности размазано во одном классе. Наследование запрещено вообще. Приложение состоит из минимального количества классов. Даже при работе с XML никаких оберток-классов — если нужны данные, вытаскиваем их по XPAth и все. Конечно из этого всего получается довольно сложная вермишель. Это я имел ввиду.

M>>Взамен предлагает вытаскивать данные в DataSet, из него XML-представление DataSet и с помощью xslt проецировать данные в новые Xml, которые представляются (юзер интрефейс).

S>Это, конечно, не единственный способ построить MVP архитектуру, но в принципе вполне жизнеспособный. Поясняю: в этом подходе данные достаются из SQL сервера за один (1) прием. Есть гарантия того, что никакая ленивая зараза не потащит какой-то хвост из базы в момент, когда уже Render поехал. Далее, нет никакого кэша объектов, который живет своей жизнью, жрет память и требует синхронизации. Всё, мы датасет забрали, теперь можно отпустить SQL сервер заниматься другой полезной работой. Импульсный режим для серверов — это самый сенокос.

Но объем данных впечатляет, я попытался сгенерить студией типизировнный DataSet только лишь для небольшой кучки таблиц из базы, сгенерированный код занимал больше 30 мегабайт. Вообще-то я думал, что память жрет как раз такой DataSet, синхронизации от тоже требует.
Преимещество датасета шеф называет автоматическое создание XSD, т.е. автоматическая валидация данных. Но по мне так, эта не та валидация, которая может быть представлена пользователю. А уж если данные проскочили через валидацию UI, то это БАГ, Exception, который нужно будет исправлять. Так накой мне этот XSD?

S>Теперь у нас, значит, поехала трансформация. В чем начальник прав? С тем, что редкий databound контрол в aspx сравнится по скорострельности отплевывания форматированного аутпута со старым добрым откомпилированным XSLT. Я надеюсь, все в курсе, что текстовый XSLT сначала парсится, потом по нему генерируется MSIL код, который затем обрабатывается джитом, и в итоге мы имеем самый что ни на есть нативный код, который шарашит по твоему XML как казак по степи?


Вообще-то это WPF-приложение, где биндинг должен будет осуществлятся к XmlDataProvider. Achtung!!! Даже не ObjectDataProvider! XMLDataProvider — который будет содержать Xml сгенерированный поле XMLT преобразований XML из DataSet.

M>>Ведь данные нужно еще редактировать, валидировать.

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

Нет не так. Данные обрабатываются, изменяются, добавляются, вычисляются.
Если бы речь шла о статических данных (например — репортинг) не было бы речи

S>а) вводиться должны не те данные, которые удобно обрабатывать и хранить, а те, которые удобно вводить. Нет ничего хуже для UI, чем generic grid и generic edit form. Введенные данные должны как-то обработаться и лечь в базу.

S>б) валидацию данных крайне вредно проводить в классах самих данных. Дело в том, что правила валидации почти никогда не бывают настолько жесткими, как модель ООП. Это скорее рекомендации, или пожелания. Вам сказали, что в почтовом индексе могут быть только цифры? Забудьте, Австралия и Англия используют буквы с цифрами. Если вы держите код валидации отдельно от данных, вам чинить такие проблемы легко и приятно. Более того, вам не нужен экземпляр класса "Покупатель" для того, чтобы проверить ввденный индекс на корректность. За это отвечает какой-то ZipFieldValidator, который никак не связан с domain model.

Хорошее замечание. учту.

SM>>Здесь опять куча утверждений, я прекрасно обхожусь с объектами и данными в них,

S>Мы говорим не о данных в объектах, а о логике в этих объектах.

M>>Извиняюсь за изложение мыслей, фактор времени давил, не сформировал до конца. Попробую еще раз. Было указанно о полезности легковесных классов, которые содержат только ту логику (алгоритмы), которая нужна, данные здесь в стороне.

S>Еще раз, на пальцах: легковесные классы в анемичной модели никакой логики не содержат. Это просто контейнеры для данных.
M>>Было интересно какое место эти алгоритмы займут в архитектуре приложения.
S>"Эти" — это какие? Поймите, ООП — это про поведение. У данных никакого поведения нет. Это не "заказ" выбирает себе "менеджера", и не "менеджер" захватывает себе заказ. Поведение есть у системы: OrderProcessingService назначает менеджера для нового заказа. Причем он запросто при этом может пользоваться ManagerSelectionService для того, чтобы абстрагироваться от алгоритма поиска подходящего менеджера.
S>Вы про эти алгоритмы говорите?

Вот как я понимаю: Есть легкий класс данных — одни поля, эти данные могут полным отображением таблицы, могут быть ее частью или объединением нескольких таблиц. Как здесь представляются связи типа один ко многим? вероятно тоже коллекции этих классов. Класс их обрабатывающий (алгоритмы) по сути должен агригировать этот легкий класс (даже упомянтуй вами способ с ManagerSelectionService, на мой взгляд, подрузамевает эту агрегацию, ваш сервис лишь подбират менеджера, который должен эти данные агрегировать). Если не пользоваться никакими дополнительными средствами (типа Linq или Entity Framework), кто знает о внутренней структуре данных, что бы мочь их сохранять или грузить? Для класса с логикой это было бы слишком много, знать как сохранять данные (работать с БД) и их же обрабатывать (абстрагируясь от BD). Получается, что как минимум работу с БД (операции сохранения, чтения) должны быть реализованны в Классах с данными (может быть не напрямую, а используя еще один слой — например шлюз). Но я опять получил ту же объектную модель.
В общем у меня пока не сходится, как использовать стройную модель.
Re[10]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.10.08 08:55
Оценка:
Здравствуйте, Mmmaloy, Вы писали:

M>Спрева слова благодарности, что теряешь со мной время.



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

От чего запрещено наследоваться?
M> Наследование запрещено вообще. Приложение состоит из минимального количества классов.
M>Даже при работе с XML никаких оберток-классов — если нужны данные, вытаскиваем их по XPAth и все. Конечно из этого всего получается довольно сложная вермишель. Это я имел ввиду.
Ну, вообще-то XPath относительно легко поправить в случае изменения структуры XML, в отличие от кода, который бегает по классам-оберткам.
Главный вопрос, который хочется себе задать: а эти классы-обёртки — они для чего?

M>Но объем данных впечатляет, я попытался сгенерить студией типизировнный DataSet только лишь для небольшой кучки таблиц из базы, сгенерированный код занимал больше 30 мегабайт. Вообще-то я думал, что память жрет как раз такой DataSet, синхронизации от тоже требует.

А зачем тебе типизированный? Для генерации XML вполне сойдет и нетипизированный.
M>Преимещество датасета шеф называет автоматическое создание XSD, т.е. автоматическая валидация данных. Но по мне так, эта не та валидация, которая может быть представлена пользователю. А уж если данные проскочили через валидацию UI, то это БАГ, Exception, который нужно будет исправлять. Так накой мне этот XSD?
Про XSD я мысль шефа не понял — рядом калорифер включен, шумит зараза в телепатическом диапазоне.

M>Вообще-то это WPF-приложение, где биндинг должен будет осуществлятся к XmlDataProvider. Achtung!!! Даже не ObjectDataProvider! XMLDataProvider — который будет содержать Xml сгенерированный поле XMLT преобразований XML из DataSet.

А в чем собственно ахтунг? Ты же не ожидаешь от ObjectDataProvider каких-то чудес в духе Дэвида Блейна?

M>Нет не так. Данные обрабатываются, изменяются, добавляются, вычисляются.

Я не о данных, а об UI. Как выглядит надводная часть айсберга? Мой любимый пример — данные о продажах. Весь Input UI — одна (1) форма ввода чека.
Зато вот отчетов на этом придумано столько, что оторопеть можно.
У тебя сколько use-case для ввода, и сколько use-case для вывода?


M>Вот как я понимаю: Есть легкий класс данных — одни поля, эти данные могут полным отображением таблицы, могут быть ее частью или объединением нескольких таблиц.

Совершенно верно.
M>Как здесь представляются связи типа один ко многим?
Непонятно, нужны ли здесь такие связи вообще. 90% алгоритмов хотят на вход однородный список неких структур. Очень-очень редко нам захочется прицепить к каждому элементу этого списка некую коллекцию (например, OrderItems к Order)

M>вероятно тоже коллекции этих классов. Класс их обрабатывающий (алгоритмы) по сути должен агригировать этот легкий класс (даже упомянтуй вами способ с ManagerSelectionService, на мой взгляд, подрузамевает эту агрегацию, ваш сервис лишь подбират менеджера, который должен эти данные агрегировать).

Продолжаю непонимать смысл слова "агрегировать" в данном контексте. Класс ManagerSelectionService вообще может быть Stateless, и никого не агрегировать.

M>Если не пользоваться никакими дополнительными средствами (типа Linq или Entity Framework), кто знает о внутренней структуре данных, что бы мочь их сохранять или грузить?

Сохранять или грузить — это самое легкое. Этим как раз может и должна заниматься инфраструктура Lightweight ORM.

M>Для класса с логикой это было бы слишком много, знать как сохранять данные (работать с БД) и их же обрабатывать (абстрагируясь от BD). Получается, что как минимум работу с БД (операции сохранения, чтения) должны быть реализованны в Классах с данными (может быть не напрямую, а используя еще один слой — например шлюз). Но я опять получил ту же объектную модель.

Нет, зачем нам это в классах с данными?
Идея примерно такая:
1. Есть технический код, который умеет доставать из базы произвольные данные и складывать их в произвольные объекты (например, NHibernate, Linq2Sql, или BLToolkit)
2. Есть совершенно ортогональная этому коду и бизнес логике анемичная модель. В продвинутых случаях далеко не все из классов этой модели вообще получат собственные имена.
3. Есть построенный на основе этого кода слой доступа к БД, специфичный для твоей модели данных. Он работает с объектами классов модели, описанной в п.2.
3. Есть слой бизнес-логики, который пользуется слоем доступа к БД.
Примернно так.
M>В общем у меня пока не сходится, как использовать стройную модель.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.10.08 09:47
Оценка:
Здравствуйте, Aikin, Вы писали:

A>Вот Иван противопоставляет стройную модель жирной: чистые контейнеры данных -- супер пупер навороченым "сам-самычам" (все делают сами).

A>Опять спор белого и черного? А как же светло-черный, темно-белый, серый наконец? Существует же огромное количество промежуточных цветов.
A>Зачем все возводить в абсолют? Если стройная, то аннорексия, если жирная, то высшая степень ожирения

Ну, мы же в форуме. Здесь без абсолюта никак
A>


A>Давайте развернем дискуссию. Начнем с конкретной реализации, а только потом займемся идеями лежащими в основе.


A>Поэтому остановимся на конкретном примере (из моего текущего проекта):

A>Система управления проектами. Ключевая сущность -- Проект. На проекте находятся люди (Participants). У проекта есть проджект лид (PL) и человек отвечающий за текущий этап работ 'Assigned To' (AT).

A>Бизнесс требования (те что есть у нас сейчас):

A>1) AT и PL может быть назначен любой пользователь системы.
A>2) При изменении AT либо PL на другого пользователья, старый должен оставаться в проекте.
A>3) AT и PL не могут быть удалены из пользователей проекта.


A>Как реализовывать эти требования в Rich модели я знаю. Работать с полученным классом будет удобно. А вот как сделать то же самое (сохранив удобство) в анемичном стиле... ума не приложу.

Я не очень понимаю, в чем основное удобство.
Я не очень понимаю, в чем проблема сделать stateless класс ProjectManagement, который хэндлит все ситуации:
public interface IProjectManagement
{
  void SetProjectLead(Project project, ParticipantId lead);
    void AssignProject(Project project, ParticipantId assignee);
    void AddParticipant(Project project, ParticipantId participant);
    void RemoveParticipant(Project project, ParticipantId participant);
}

Ну да, у всех методов первый аргумент получился Project. Но фишка в том, что ты можешь поменять этот класс, не меняя модели данных — например, сделать так, чтобы проверялось отсутствие двойных назначений сотрудников, или отсутствие тройных назначений, или еще что-нибудь. Или, например, можно сделать так, чтобы удаление ProjectLead с проекта было не запрещено, а вместо него автоназначался его заместитель.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: роль ООП при работе с данными
От: Аноним  
Дата: 22.10.08 10:37
Оценка:
M>>Запрещается наследоваться что бы расширить функционал, запрещается агрегация что бы скрыть лишние свойсвтва объектов, все должно быть по возможности размазано во одном классе.
S>От чего запрещено наследоваться?

На это есть много названных и неназванных причин, но похоже склад ума по всей видимости у шефа такой. Не может он объектами оперировать, а может не хочет. Мне по-началу довелось один проект его разгребать (не он сам писал, но под его чутким руководством), где все в кучу свалено было да еще и MultiThreading. Баги вылазили в непонятных местах. В конце концов заглохло. Тогда, у него просто небыло шансов, заказчик давил, и без его напора и контроля все по объектам распределил и все складно заработало. Сейчас начинает на меня наседать, от ООП подхода отказываться. Максимум на что я могу наедеятся это на расширение через partial class.

S>Ну, вообще-то XPath относительно легко поправить в случае изменения структуры XML, в отличие от кода, который бегает по классам-оберткам.

S>Главный вопрос, который хочется себе задать: а эти классы-обёртки — они для чего?

Ну как сказать, есть много причин. Одна из самых банальных — каждый раз не нужно вспоминать как там этот тэг в XML называется. Ну или изменится Xpath путь к какому-то тегу, что по всему коду потом скакать и отлавливать. Такие ошибки компилятор не ловит. Поважнее аргумент: Xml — закрытый объект, как реагировать на изменения данных этого объекта? Это важно в контекте WPF программы, биндинг вообще то предназначен не для односторонней передачи данных, иногда важно знать что пользователь изменил значение на уровне объекта.

S>А зачем тебе типизированный? Для генерации XML вполне сойдет и нетипизированный.


Тоже несколько (не моих) причин. Ну потому что генерируеца схема XSD, которая может использоваться для валидации данных. Вообще данные храняться только лишь в datasete или в контролах интрефейса. Валидацию данных в ДатаСете получаем автоматически. И потом, типизированный датасет можно расширять через partial class, а значить редуцировать количество ошибок, которые может создать программист. Что-то в этом духе...

M>>Вообще-то это WPF-приложение, где биндинг должен будет осуществлятся к XmlDataProvider. Achtung!!! Даже не ObjectDataProvider! XMLDataProvider — который будет содержать Xml сгенерированный поле XMLT преобразований XML из DataSet.

S>А в чем собственно ахтунг? Ты же не ожидаешь от ObjectDataProvider каких-то чудес в духе Дэвида Блейна?

Собственно выше объяснил: Если мой объект, то могу двусторонней биндинг обрабатывать.

M>>Нет не так. Данные обрабатываются, изменяются, добавляются, вычисляются.

S>Я не о данных, а об UI. Как выглядит надводная часть айсберга? Мой любимый пример — данные о продажах. Весь Input UI — одна (1) форма ввода чека.
S>Зато вот отчетов на этом придумано столько, что оторопеть можно.
S>У тебя сколько use-case для ввода, и сколько use-case для вывода?

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

Остальную часть про анемик модель я пока опускаю, потому как надо самому поковыряться.
Re[12]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 22.10.08 10:48
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>На это есть много названных и неназванных причин, но похоже склад ума по всей видимости у шефа такой.

Я не спрашиваю "почему". Я спрашиваю "от чего". В смысле — от каких объектов.

А>Не может он объектами оперировать, а может не хочет. Мне по-началу довелось один проект его разгребать (не он сам писал, но под его чутким руководством), где все в кучу свалено было да еще и MultiThreading. Баги вылазили в непонятных местах. В конце концов заглохло. Тогда, у него просто небыло шансов, заказчик давил, и без его напора и контроля все по объектам распределил и все складно заработало. Сейчас начинает на меня наседать, от ООП подхода отказываться. Максимум на что я могу наедеятся это на расширение через partial class.

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

А>Ну как сказать, есть много причин. Одна из самых банальных — каждый раз не нужно вспоминать как там этот тэг в XML называется.

Какой тег?

А>Ну или изменится Xpath путь к какому-то тегу, что по всему коду потом скакать и отлавливать.

А у вас XPath предполагается по всему коду? Сочувствую.
Не понимаю, почему нельзя применить ООП по назначению — сделать класс, ответственный за доставание некоторых данных из XML, и в нем упрятать все нужные XPath запросы.
А>Такие ошибки компилятор не ловит. Поважнее аргумент: Xml — закрытый объект, как реагировать на изменения данных этого объекта? Это важно в контекте WPF программы, биндинг вообще то предназначен не для односторонней передачи данных, иногда важно знать что пользователь изменил значение на уровне объекта.
Тут я пас — я про WPF ничего не знаю.

А>Тоже несколько (не моих) причин. Ну потому что генерируеца схема XSD, которая может использоваться для валидации данных.

Ничего не понимаю. Схема полностью ортогональна типу датасета.
А>Вообще данные храняться только лишь в datasete или в контролах интрефейса. Валидацию данных в ДатаСете получаем автоматически. И потом, типизированный датасет можно расширять через partial class, а значить редуцировать количество ошибок, которые может создать программист. Что-то в этом духе...
А зачем его расширять?

А>Собственно выше объяснил: Если мой объект, то могу двусторонней биндинг обрабатывать.

Ну, тогда возможно XmlDataSource не подойдет. Я не в курсе.

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

М-м. Наверное, стоит потратить усилия на то, чтобы все стало достаточно просто.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: роль ООП при работе с данными
От: Аноним  
Дата: 22.10.08 11:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, <Аноним>, Вы писали:


S>Я не спрашиваю "почему". Я спрашиваю "от чего". В смысле — от каких объектов.

от всех классов, своих и классов библиотеки c#

S>Я не понимаю, что именно вы называете "ООП" подходом. Вообще, без ООП на шарпе писать не получится никак — так язык устроен.


можно. я не имею ввиду объекториентированный арсенал FCL, или ООП которое навязывается (например наследование форм, или USerControl). Имеется ввиду та часть приложения, которая разрабатывается программистом. Вот здесь можно про ООП и его принципы забыть, спихнуть все в кучу в пару классов длинной несколько тысяч строк кода и радоваться этой лапше.

S>Приведите пример, что от чего вы хотели отнаследовать, а злой шеф запретил.


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

А>>Ну как сказать, есть много причин. Одна из самых банальных — каждый раз не нужно вспоминать как там этот тэг в XML называется.

S>Какой тег?
Элементы XML-Документа

А>>Ну или изменится Xpath путь к какому-то тегу, что по всему коду потом скакать и отлавливать.

S>А у вас XPath предполагается по всему коду? Сочувствую.
S>Не понимаю, почему нельзя применить ООП по назначению — сделать класс, ответственный за доставание некоторых данных из XML, и в нем упрятать все нужные XPath запросы.

А>>Такие ошибки компилятор не ловит. Поважнее аргумент: Xml — закрытый объект, как реагировать на изменения данных этого объекта? Это важно в контекте WPF программы, биндинг вообще то предназначен не для односторонней передачи данных, иногда важно знать что пользователь изменил значение на уровне объекта.

S>Тут я пас — я про WPF ничего не знаю.

А>>Тоже несколько (не моих) причин. Ну потому что генерируеца схема XSD, которая может использоваться для валидации данных.

S>Ничего не понимаю. Схема полностью ортогональна типу датасета.

Тоже не понимаю

А>>Вообще данные храняться только лишь в datasete или в контролах интрефейса. Валидацию данных в ДатаСете получаем автоматически. И потом, типизированный датасет можно расширять через partial class, а значить редуцировать количество ошибок, которые может создать программист. Что-то в этом духе...

S>А зачем его расширять?

Не знаю.
Когда я начал обьяснить что логику обработки данных в XML невпихнешь, был дан ответ, что вот расширим DataSet через partial class

А>>Собственно выше объяснил: Если мой объект, то могу двусторонней биндинг обрабатывать.

S>Ну, тогда возможно XmlDataSource не подойдет. Я не в курсе.

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

S>М-м. Наверное, стоит потратить усилия на то, чтобы все стало достаточно просто.
Re[5]: роль ООП при работе с данными
От: Aikin Беларусь kavaleu.ru
Дата: 22.10.08 11:47
Оценка: 93 (1) +2
Здравствуйте, Sinclair, Вы писали:

S>
S>public interface IProjectManagement
S>

Согласен. Это именно этого я и ожидал.

Что мне не нравится в этом подходе:
1) Вместо одного класса получаем целых два. Причем наличие второго неочевидно без прочтения документации. Как следствие увеличение вероятности ошибки при работы с сущностью Проект.
2) Экземпляр проекта очень легко перевести в невалидное состояние (достаточно забыть/не знать про менеджер), элементарно захардкодить поведение в "третьей слева в пятом ряду" странице которая может поломать систему после изменения требований.
Да, можно добавить в IProjectManagement метод Validate(Project project) он решит большинство проблем. Но, ИМХО, лучше не допускать перевода в невалидное состояние защитившись контрактом, чем в рантайме получать ProjectNotValidException.
3) Рано или поздно возникнет вопрос "если я могу изменить проект напрямую, зачем мне менеджер?" (см. PS)




В случае же насыщенной модели этих проблем нет:
1) Разработчик имеет дело только с одним классом (то что внутри там два или три класса его волнует мало).
2) Экземпляр класса защищен контрактом.
3) Отпадает сам собой.

Да, появляются другие (куда ж без них):
1) Сложности с инициализацией восстановленного из базы объекта.
2) Аналогично 1) но в отношении классов менящих состояние объекта (см. пример ниже).
3) Пляски с фабриками, если нам для инициализации объекта нужны сторонние сервисы (такие как IProjectManagement ниже).


Не скажу, что эти проблемы проще. Нет, они даже сложнее. Но они изолированны в сервисных слоях: 1 в DataAccess слое, 2) в Домене, 3) в сервисном слое. Причем 1) и 3) использует функциональность предоставленную самим доменом.
Которые (теоретически) должны редко менятся (особенно при наличии подключаемой функциональности).


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

Сомнительное приемущество в моем случае (у меня один заказчик) которое можно получить и в насыщенной модели:
public class Project
{
    private IProjectManagement _manager; // как-то инджектится в проект
    
    public Participant ProjectLead
    {
        get {return _projectLead;}
        
        set
        {
            _manager.SetProjectLead(this, value); // каким-то образом менеджер устанавливает свойства
        }
    }
}





P.S. В этом же проекте предыдущие разработчики очень сильно потрудились на тему "изменение состояния объекта в обход менеджеров". Делалось это не сложно: выгружались потроха объекта в XML, он правился нужным образом и заливался назад. Мой коллега (видя что именно так идет работа) так же грешил этим, так как изменить поле в объекте много легче и понятнее, чем добавлять метод в менеджер (мне тяжело было переубедить его в этом, да и то не уверен, что он все до конца осознал). В итоге, нам стоило больших трудов избавиться от таких хардкодов (хотя я не уверен что мы вычистили все такие места).
Re[6]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 23.10.08 06:56
Оценка: 4 (3) +1
Здравствуйте, Aikin, Вы писали:

A>1) Вместо одного класса получаем целых два.

Лучше два маленьких класса, чем один большой. За подробностями почему так, отсылаю все к тем же набившим оскомину SRP, OCP, инкапсуляции, принципу минимиации интерфейса, низкой связности и пользе хорошо прописанных формальных контрактов.
Про остальное ниже.

A>Причем наличие второго неочевидно без прочтения документации. Как следствие увеличение вероятности ошибки при работы с сущностью Проект.

A>2) Экземпляр проекта очень легко перевести в невалидное состояние (достаточно забыть/не знать про менеджер), элементарно захардкодить поведение в "третьей слева в пятом ряду" странице которая может поломать систему после изменения требований.
A>Да, можно добавить в IProjectManagement метод Validate(Project project) он решит большинство проблем. Но, ИМХО, лучше не допускать перевода в невалидное состояние защитившись контрактом, чем в рантайме получать ProjectNotValidException.
A>3) Рано или поздно возникнет вопрос "если я могу изменить проект напрямую, зачем мне менеджер?" (см. PS)
Это все паранойя, сейчас объясню почему.
Когда разработчик садится писать код, для решения какой либо бизнес-задачи, эта самая бизнес задача формируется ему не в терминах "вот тебе заказ, сделай с ним то-то", а в терминах "мне нужно получить такую-то информацию из заказов". То есть, на первом месте идет функционал, который надо получить/найти/реализовать, а не объект над которым нужно что-то сделать, соответственно, решать эту задачу он начинает не с "ну вот у меня заказ, что бы с ним сделать", а с "где эта хрень, которую мне надо сделать", как следствие он в первую очередь находит именно нужный сервис/менеджер, а потом уже объект содержащий заказ.
Если же все-таки паранойя не дает спать спокойно, есть комплекс простых средств, рецепт прост и незатейлив:
1. Extension Methods
2. Все объекты стройной модели делаются immutable — все свойства readonly, запись свойств только через конструктор, соответственно, изменение только через создание нового экземпляра. Это накорню убивает все попытки поправить объект напрямую и стимулирует найти нужный сервис. Кроме того, сервис создавший объект имеет гарантию, что этот объект всегда останется в нужном ему состоянии.
3. Грамотное разделение проекта на неймспейсы и тщательное продумыванеи структуры (mast have даже при отсутствии паранойи) — этот пункт позволяет избавиться от документации и изнурительных поисков нужного сервиса. Код вообщем-то не плохо самодокументируется.

A>2) Экземпляр класса защищен контрактом.

Не защищен. Просто контракт стал еще толще, соответственно, больше шансов, что что-то сломается при изменении.

A>3) Отпадает сам собой.

Нет, не отпадает. Объект точно так же можно поменять снаружи, в обход всех методов и никто не запретит это сделать.

A> Но они изолированны в сервисных слоях: 1 в DataAccess слое, 2) в Домене, 3) в сервисном слое.

Стройная модель так же отлично бъется по слоям.

A>Сомнительное приемущество в моем случае (у меня один заказчик) которое можно получить и в насыщенной модели:

A> private IProjectManagement _manager; // как-то инджектится в проект
Ты там выше был против большого количества классов, а большое количество pass thru методов тебя не смущает?
Практически на каждый новый метод в сервисе ты должен менять класс модели и писать заглушку для этого метода там.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[3]: роль ООП при работе с данными
От: Ziaw Россия  
Дата: 24.10.08 09:27
Оценка: 3 (1) +1
Здравствуйте, IB, Вы писали:

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

IB>Я специально старался нигде не затронуть ни NH, ни любой другой ORM инструмент, чтобы не ввязываться в бесполезные религиозные споры. Я лишь констатировал тот факт, что _разработички_ NH являются сторонниками "жирной" модели. О чем недвусмысленно заявлено в их манифесте: "The Entity Framework encourages the Anemic Domain Model anti-pattern by discouraging the inclusion of business logic in the entity classes".

Интересно. Можно узнать кто из разработчиков автор этого открытого письма? Как разработчики NH виляют на принципы NH, который всеголишь порт java-hibernate? Ты снова воюешь с одним инструментом и защищаешь другой, скрывая суть статьи — anemic model > rich model. Зачем? Вроде уже куча копий переломана по поводу инструментов, ветка ну очень внушительная да и к сути статьи данный холивар не имеет отношения.

IB>В отличии от них, я считаю антипаттерном именно Rich модель, а Anemic, как раз очень правильным паттерном. Почему я так считаю, я и описал в данной статье.


Вот если бы ты писал только это — было бы просто чудесно. Но первый прозвучавший лозунг — "создатели NH кормят вас неправильным медом, ешьте правильный мед от создателей EF, да, он не сладкий, но сладкое вредно" уже настолько набил оскомину, что читать не хочется.

А теперь по сути: "жирная" модель при всех ее недостатках обладает своими достоинствами, но я сейчас не об этом противостоянии. Я о том, что NH позволяет использовать обе модели, причем никак не толкая к любой одной из них, по крайней мере все подталкивания которые я видел — косвенные упоминания от тебя, Синклера и Влада2, а я немало почитал блогов о (N)Hibernate.

Теперь зададимся вопросом, почему EF нас подталкивает к использованию anemic model? Оказывается, что для бизнеслогики размещенной в классах сущностей очень быстро наступает момент, когда данных в this становится недостаточно, соответственно логика должна уметь, как минимум, загружать нужные ей данные. Но прямая связь сущности с механизмом ее загрузки довольно хорошо раскритикована многими именитыми арихитекторами. Именно это основной минус rich модели: как только ей понадобились другие сущности, мы тут же начинаем нарушать SRP. Для обхода жесткой связи с загрузкой нужных объектов был придуман трекинг по свойствам, а для борьбы с оверхедом загрузки лишних данных пришлось придумать ленивую загрузку. Так вот именно ее и не реализовали создатели EF. Т.o. использовать rich model в EF можно только ценой просадки производительности (изза отсутствия LL) либо используя вместо трекинга другие механизмы загрузки данных.

Большинство аргументов против NH с которыми я согласен — это аргументы как раз против трекинга и навигационного поиска нужных сущностей. Это действительно очень неприятный механизм, т.к. он в общем случае неэффективно использует механизмы РСУБД и привносит чрезмерно выскокий уровень абстракции над механизмами загрузки данных. Это и есть основное зло ORM с которым стоит бороться. Да, EF может заставить отказаться от него, а может заставить изобрести свой LL велосипед.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[4]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 24.10.08 10:29
Оценка: :)
Здравствуйте, Ziaw, Вы писали:

Z>Интересно. Можно узнать кто из разработчиков автор этого открытого письма?

Гугл тебе поможет, ключевые слова "Vote of no confidence".

Z> Как разработчики NH виляют на принципы NH, который всеголишь порт java-hibernate? Ты снова воюешь с одним инструментом и защищаешь другой,

Вашу мать. Давай цитату, где я хоть слово сказал про гибернейт.
Сколько раз можно повторять, что там было лишь упоминаие, что к числу защитников жирной модели, относятся Фаулер и разработчики Nhibernate. Я специально, для самых занудных даже дисклаймер написал, что возможности гибернейта и любого другого ORM меня не парят вообще ни в одном месте, и я не имею желания и не собираюсь их обсуждать.
Где в этом посте хоть слово именно про гибернейт?

Z>Вот если бы ты писал только это — было бы просто чудесно.

А я только про это и написал. Все остальное — плод воспаленной фантазии защитников NH на ровном месте.

Z>Но первый прозвучавший лозунг — "создатели NH кормят вас неправильным медом, ешьте правильный мед от создателей EF, да, он не сладкий, но сладкое вредно" уже настолько набил оскомину, что читать не хочется.

Не хочется — не читай, никто не заставляет.

Z> Я о том, что NH позволяет использовать обе модели,

Это исключительно проблемы NH.

Z>Именно это основной минус rich модели: как только ей понадобились другие сущности, мы тут же начинаем нарушать SRP.

Принцип SRP начинает нарушаться гораздо раньше.

Z> Т.o. использовать rich model в EF можно только ценой просадки производительности (изза отсутствия LL) либо используя вместо трекинга другие механизмы загрузки данных.

Либо реализовав свой LL, что на самом деле доволно просто. Но это все лирика.
Поинт в том, что в связи с порочностью жирной модели это все лишний функционал.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[5]: роль ООП при работе с данными
От: Ziaw Россия  
Дата: 24.10.08 10:59
Оценка: +1
Здравствуйте, IB, Вы писали:

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


Z>>Интересно. Можно узнать кто из разработчиков автор этого открытого письма?

IB>Гугл тебе поможет, ключевые слова "Vote of no confidence".

Z>> Как разработчики NH виляют на принципы NH, который всеголишь порт java-hibernate? Ты снова воюешь с одним инструментом и защищаешь другой,

IB>Вашу мать. Давай цитату, где я хоть слово сказал про гибернейт.
IB>Сколько раз можно повторять, что там было лишь упоминаие, что к числу защитников жирной модели, относятся Фаулер и разработчики Nhibernate. Я специально, для самых занудных даже дисклаймер написал, что возможности гибернейта и любого другого ORM меня не парят вообще ни в одном месте, и я не имею желания и не собираюсь их обсуждать.

Сторонники "Жирной" (Rich) модели (к числу которых относятся и разработчики NHibernate), моментально нашли фатальный недостаток в EF — он провоцирует работать с данными "Стройном" (Anemic) стиле, и принялись с усердием обличать в этом EF...


Ты смешал жирную модель, Фаулера, NHibernate и EF. Последние 3 сущности лишние в в дискуссии anemic/rich. Фаулер описывает rich model как один из подходов, этот дядька тем и хорош, что описывает все подходы, а не доказывает заведомую "лучшесть" одного. Anemic model он называет антипатерном только для pure DDD систем, и в этом есть смысл. Почему лишние EF и NH я уже написал.

IB>Где в этом посте хоть слово именно про гибернейт?


Я обсуждал не только пост, но и статью

Z>>Именно это основной минус rich модели: как только ей понадобились другие сущности, мы тут же начинаем нарушать SRP.

IB>Принцип SRP начинает нарушаться гораздо раньше.

Это лишь твое мнение, что хранение данных достаточная ответственность, чтобы ее выделить в отдельную сущность. Я с ней не согласен. (сам лично последние полтора года использую anemic model, но по другим причинам).

Z>> Т.o. использовать rich model в EF можно только ценой просадки производительности (изза отсутствия LL) либо используя вместо трекинга другие механизмы загрузки данных.

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

Ты смешиваешь мух и котлеты. Трекинг и жирность модели пересекаются довольно слабо. Можно сделать жирную модель без трекинга и тощую с трекингом.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[6]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 24.10.08 11:30
Оценка: +1
Здравствуйте, Ziaw, Вы писали:

Z>

Сторонники "Жирной" (Rich) модели (к числу которых относятся и разработчики NHibernate), моментально нашли фатальный недостаток в EF — он провоцирует работать с данными "Стройном" (Anemic) стиле, и принялись с усердием обличать в этом EF...

Так где здесь хоть слово про гибернейт?

Z>Ты смешал жирную модель, Фаулера, NHibernate и EF.

Если тут у кого-то что-то смешалось, то точно не у меня.
Давай еще раз, если по прежнему непонятно: Есть авторы NH, совершенно конкретные люди. Есть Фаулер, тоже конкретный человек, но другой. У них есть мнение и они это мнение высказали. Конкретно у авторов NH есть мнение, что "EF не поддерживает жирную модель, в чем его огромный недостаток, так как жирная модель это хорошо". Упомянул я об этом, чтобы было понятно, что эту точку зрения я взял не с потолка и что действительно есть люди, кторые заблуждаются подобным образом.
Мне по прежнему непонятно, какой еще смысл можно извлечь из процитированного куска и в чем тут смешение, тем более с NH про который вообще ни слова.

Z> Последние 3 сущности лишние в в дискуссии anemic/rich.

Ага, тем более, что одной там вообще нет, а про две другие ты прочитал совсем не то что было написано.

Z> Фаулер описывает rich model как один из подходов,

Фаулер выступает конкретным критиком стройной модели.

Z>этот дядька тем и хорош, что описывает все подходы, а не доказывает заведомую "лучшесть" одного.

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

Z> Anemic model он называет антипатерном только для pure DDD систем, и в этом есть смысл.

Ага, толкователи Фаулера подтянулись. В своей критике стройной модели он нигде не упоминает, что речь идет только о DDD.

Z> Почему лишние EF и NH я уже написал.

Лучше бы прочитал сначала, ей богу.

Z>Я обсуждал не только пост, но и статью

Я "статью" и имел ввиду (это все-таки не статья, а пост в блоге), так где там хоть слово про NH? По прежнему жду цитаты.

Z>Это лишь твое мнение, что хранение данных достаточная ответственность, чтобы ее выделить в отдельную сущность.

Это не только мое мнение, это объективная реальность.

Z> Я с ней не согласен.

Твое право, но тем не менее SRP в жирной модели нарушается гораздо раньше.

Z>Ты смешиваешь мух и котлеты.

Z> Трекинг и жирность модели пересекаются довольно слабо. Можно сделать жирную модель без трекинга и тощую с трекингом.
Это ты к чему? Где я хоть слово написал про трекинг?

Слушай у меня вообще складываается ощущение, что ты беседуешь не со мной, а с какими-то своими вольными интерпретациями на заданную тему.
Если что-то непонятно, спроси лучше у меня, а не фантазируй.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[7]: роль ООП при работе с данными
От: Torvin  
Дата: 26.10.08 17:05
Оценка: +2
так, ну я не знаю как автора вопросов, Aikin-а, а меня данные на них ответы категорически не устроили

A>>2) Экземпляр проекта очень легко перевести в невалидное состояние

IB>Это все паранойя, сейчас объясню почему.
IB>2. Все объекты стройной модели делаются immutable — все свойства readonly, запись свойств только через конструктор, соответственно...
...соответственно, при необходимости переименовать project придется создать новый экземпляр. и что делать с ссылками на старые экземпляры, представляющими ту же самую сущность — ни разу не понятно

A>>2) Экземпляр класса защищен контрактом.

IB>Не защищен. Просто контракт стал еще толще, соответственно, больше шансов, что что-то сломается при изменении.
зато все "опасные" изменения находятся в известном месте — внутри. так что вы застрахованы от ужаса через некоторое время обнаружить что ваш любимый коллега Петя ровным слоем по всему проекту разбросал строки в духе
project.ID++;

и как их теперь найти и повыковыривать — не понятно
это в случае mutable сущностей. в случае immutable — см вопрос выше


PS
IB> В случае жирной модели он занимается именно доказательством ее "лучшести" причем с весьма натянутыми аргументами.
....
Z>Это лишь твое мнение, что хранение данных достаточная ответственность, чтобы ее выделить в отдельную сущность.
IB>Это не только мое мнение, это объективная реальность.
я смотрю у Вас с аргументация ровно такая же как у Мартина. знаете поговорку про бревно в глазу?
Re[8]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 26.10.08 18:14
Оценка:
Здравствуйте, Torvin, Вы писали:

T>...соответственно, при необходимости переименовать project придется создать новый экземпляр.

T>и что делать с ссылками на старые экземпляры, представляющими ту же самую сущность — ни разу не понятно
Очень даже понятно — либо просто грохнуть, если это кеш, либо обновить, либо вообще ничего не делать, если не актуально.
Вообще, с immutable сущностями как раз проблем нет, проблемы именно с mutable, когда они меняются неожиданно для кода имеющего на него ссылку. При работе со строками у тебя же проблем не возникает?
Да что там строки, есть целые языки, которые отлично себя чувствуют без изменяемых объектов, вся функциональщина на этом построена.

T>зато все "опасные" изменения находятся в известном месте — внутри.

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

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

T>
T>project.ID++;
T>

В том-то и дело, что не застрахованы, так как ID все равно торчит наружу и никто не помешает любимому коллеге сделать тоже самое.
Мы уже победили, просто это еще не так заметно...
Re[9]: роль ООП при работе с данными
От: Torvin  
Дата: 26.10.08 18:23
Оценка:
Здравствуйте, IB, Вы писали:

IB>При работе со строками у тебя же проблем не возникает?

для строк immutable — это эмуляция поведения value-типа. для сложных объектов (т.е. состоящих из нескольких полей) я себе этого не представляю

IB>Да что там строки, есть целые языки, которые отлично себя чувствуют без изменяемых объектов, вся функциональщина на этом построена.

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

T>>зато все "опасные" изменения находятся в известном месте — внутри.

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

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

T>>
T>>project.ID++;
T>>

IB>В том-то и дело, что не застрахованы, так как ID все равно торчит наружу и никто не помешает любимому коллеге сделать тоже самое.
в том то и дело что застрахованы. любому нормальному человеку, пишущему код на основе жирной модели никогда не придет в голову делать поле ID writable. потому что в этом нет никакой необходимости
Re[6]: роль ООП при работе с данными
От: Кэр  
Дата: 26.10.08 18:44
Оценка: 3 (1)
Здравствуйте, Aikin, Вы писали:

A>2) Экземпляр проекта очень легко перевести в невалидное состояние (достаточно забыть/не знать про менеджер), элементарно захардкодить поведение в "третьей слева в пятом ряду" странице которая может поломать систему после изменения требований.

A>Да, можно добавить в IProjectManagement метод Validate(Project project) он решит большинство проблем. Но, ИМХО, лучше не допускать перевода в невалидное состояние защитившись контрактом, чем в рантайме получать ProjectNotValidException.

Невалидное состояние объекта — это рабочая ситуация. Я не знаю, надо ли кидать ProjectNotValidException — чаще всего должно хватать метода
bool Validate(Project)
. Дело в том, что если у нас есть объект Project — этакая непорочная фифа, которая ни-ни, ни в жисть не окажется в невалидном состоянии — то нам вполне вероятно потребуется таскать нормальный рабочий объект, какой-нибудь ProjectData (либо кучку бесвязных параметров, которые еще нельзя запихать в Project, и которые со временем будут только пухнуть), который можно заполнять по мере возможности (несколько этапов заполнения объекта — через несколько форм ввода, данные приходят из разных сервисов и пр.).

Остальные оба пункта тоже надуманные Преимущества же подхода, когда мы Project ограничиваем контрактом и логику пихаем в этот объект меня только больше убеждают, что так делать все же не стоит.
Re[10]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 26.10.08 19:24
Оценка:
Здравствуйте, Torvin, Вы писали:

T>для сложных объектов (т.е. состоящих из нескольких полей) я себе этого не представляю

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

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

На лиспе, к слову GC в .Net написан, так что не надо про сферических коней.. )
Вообщем, если лень проверять, то придется поверить на слово — в реальной жизни от immutable объектов только польза.

T>точно так же как и при использовании Вашего подхода,

Боюсь, ты не очень внимательно читал.

T> просто в нашем случае по крайней мере известно где искать грабли

Я предпочитаю, чтобы за меня их находил компилятор.

T>любому нормальному человеку, пишущему код на основе жирной модели никогда не придет в голову делать поле ID writable. потому что в этом нет никакой необходимости

Ты сам себе противоречишь. Почему в одном случае ID обязательно делать изменяемым, чтобы избежать каких-то мифических проблем с immutable, а в другом этого делать нет никакой необходимости?
Мы уже победили, просто это еще не так заметно...
Re[10]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 27.10.08 06:57
Оценка:
Здравствуйте, Torvin, Вы писали:
T>для строк immutable — это эмуляция поведения value-типа. для сложных объектов (т.е. состоящих из нескольких полей) я себе этого не представляю
Для улучшения представлений рекомендую познакомиться с DateTime.
Ты в курсе того, что в Яве приходится со страшной силой приседать, чтобы только не дать стороннему коду надругаться над person.GetBirthday() произвольным образом? Это только потому, что даты в яве — mutable.
Практика применения показывает, что никаких трудностей со сложными датами у программистов не возникает.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: роль ООП при работе с данными
От: Ziaw Россия  
Дата: 27.10.08 08:11
Оценка: 19 (2) +2
Здравствуйте, IB, Вы писали:

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

IB>Если что-то непонятно, спроси лучше у меня, а не фантазируй.

Непонятно кто из авторов NH написал Vote of no confidence (прежде чем первый раз спросить, я поискал, гугл дает много ссылок на блоги в которых оно упоминается и не дал мне ссылки на авторов, все что удалось понять, это то, что это плод коллективного разума ALT.NET community. так что ответ "ищи в гугле" меня только позабавил, если бы ты точно знал какого-то автора письма и по совместительству "автора" NH тебя бы не затруднило написать имя). Непонятно почему они записаны в сторонники rich модели (недовольство тем, что инструмент заточен только под одну модель еще не означает упертость человека в другую).
Более менее понятно, почему ты записал туда Фаулера (пусть я и не согласен с тем, что он упертый сторонник rich модели).

Непонятно почему ты не затрудняешь себя аргументацией выдвинутого тобой(?) тезиса:

- Single Responsibility Principle (SRP). Хранение данных в классе — это уже одна, вполне самостоятельная обязанность, добавление другой логики в класс приводит к нарущению этого принципа.

крайне спорное утверждение на мой вгляд

Непонятно почему критикуя rich model ты приводишь в пример ActiveRecord:

Если, следуя логике "жирной" модели, класс с персистентными данными оборудован методом .Save(), сохраняющим данные в БД


Непонятно почему отсутствие возможности LL объявляется провокацией проектировать anemic model (на самом деле оно просто лишает возможностей трекинга).

Непонятно почему однобокость инструмента объявляется достоинством (если бы он был лучше других заточен под anemic model, так ведь нет, просто не умеет LL).

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

И, возвращаясь к Entity Framework, в свете всего вышеописанного, тот факт, что он "провоцирует" проектировать приложения в "стройной" модели и не поддерживает Lazy Loading, требуя явной загрузки всех необходимых данных, я склонен считать достоинством.


P.S. Непонятна также твоя манера дискутировать. Намекнуть на то, что собеседник псих беседующий со своими фантазиями это нормальный прием?
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[8]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 27.10.08 11:08
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Непонятно кто из авторов NH написал Vote of no confidence

Конкретно Ayende Rahien тоже в нем учавствовал и подписывал.

Z> так что ответ "ищи в гугле" меня только позабавил,

Ну, не ждешь же ты, что я буду это делаь за тебя?

Z>если бы ты точно знал какого-то автора письма и по совместительству "автора" NH тебя бы не затруднило написать имя).

А то я их всех запоминать буду, вот это действительно было бы забавно.

Z> Непонятно почему они записаны в сторонники rich модели (недовольство тем, что инструмент заточен только под одну модель еще не означает упертость человека в другую).

Ты хоть читал этот Vote? Или ты опять начинаешь вольной трактовкой заниматься? "... The Entity Framework encourages the Anemic Domain Model anti-pattern ...", и прочая риторика направленная на то, что стройный стиль — это отстой, а жирный — рулит всегда, "как подтверджает наш многолетнйи опыт", ага. На мой взгляд трактовка этой петиции конкретная и однозначная — авторы однозначные сторонники жирной модели и критикуют MS за то, что он пошел другим путем. И отмазки — "на самом деле они имели ввиду, что поддержать надо все", смотрятся бледно.

Z>Непонятно почему ты не затрудняешь себя аргументацией выдвинутого тобой(?) тезиса:

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

Z>Непонятно почему критикуя rich model ты приводишь в пример ActiveRecord:

Z>

Если, следуя логике "жирной" модели, класс с персистентными данными оборудован методом .Save(), сохраняющим данные в БД

Ок, понесись по третьему кругу: Потому что метод Save(), в данном случае, ничем не отличается от метода Calculate(), так просто нагляднее.

Z>Непонятно почему отсутствие возможности LL объявляется провокацией проектировать anemic model (на самом деле оно просто лишает возможностей трекинга).

А это вообще не ко мне претензии, а авторам петиции, это их тезис.
Кроме того, это вообще-то две отдельных претензии, и как ты умудрился их смешать — для меня загадка.

Z>Непонятно почему однобокость инструмента объявляется достоинством

По той причине, что лишний и кривой функционал это определенно недостаток. А отсутствие недостатка, в определенном смысле является достоинством.

Z>(если бы он был лучше других заточен под anemic model, так ведь нет, просто не умеет LL).

Где я писал, что он лучше других заточен под стройную модель? Где я вообще писал, что он хоть в чем-то лучше других? (кроме отсутствия лишнего функционала, естетственно)

Z>Непонятно почему это утверждение ставится в конце поста,

Потому что я его там поставил.

Z>вследствии этого весь пост выглядит как доказательство данного тезиса:

И что тебя в данном тезисе неустраивает?

Z>P.S. Непонятна также твоя манера дискутировать. Намекнуть на то, что собеседник псих беседующий со своими фантазиями это нормальный прием?

Ну, начнем с того, что ты сам занимаешься прикладной демагогией — я нигде не намекал, что собеседник псих.
С другой стороны, ты определенно споришь совсем не с тем, что я написал, а с какой-то вывернутой версией, где я затрудняюсь даже воспроизвести логику, которой ты руководствовался, придумывая за меня аргументы.
Выводы из всего этого можно сделать следующие: Либо ты, всетаки, очень хочешь поговорить со мной на тему NHibernate и EF и ORM вообще, и таким сомнительным способом пытаешься вовлечь меня в это дело, ну не вопрос давай тогда откроем отдельный топик, так как к обсуждаемой теме это не имеет никакого отношения. Либо ты пытаешься рассказать мне, что я на самом деле имел ввиду, когда писал этот пост в блоге. В этом случае предлагаю дальнейшую дискуссию прекратить, за очевидной бесполезностью.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[9]: роль ООП при работе с данными
От: Ziaw Россия  
Дата: 27.10.08 13:06
Оценка: +2 -2
Здравствуйте, IB, Вы писали:

Z>>Непонятно кто из авторов NH написал Vote of no confidence

IB>Конкретно Ayende Rahien тоже в нем учавствовал и подписывал.
Приятнуто за уши, называть Ayende автором NH как-то странно. Причины: NHibernate всеголишь порт Hibernate, идеологию они не определяют, авторство тут некорректный термин. Подписал документ он аж 29ым, налицо передергивание.

Факт:

документ который содержит строку: "The Entity Framework encourages the Anemic Domain Model anti-pattern by discouraging the inclusion of business logic in the entity classes" подписали 580 человек, в чиcле них и один из разработчиков портирующих hibernate под платформу .NET



Подача:

Сторонники "Жирной" (Rich) модели (к числу которых относятся и разработчики NHibernate), моментально нашли фатальный недостаток в EF — он провоцирует работать с данными "Стройном" (Anemic) стиле, и принялись с усердием обличать в этом EF...


Для красного словца, кстати, выдумана фатальность именно этого недостатка, как будто письмо построено на этой фразе. На самом деле там полно другой критики по существу. Для красного словца же выдумана терминология в стиле плохой/хороший. Это хорошо в предвыборной борьбе, в технической статье как-то странно выглядит. Мало решений на основе PR'а в IT принимается что-ли?

Z>> так что ответ "ищи в гугле" меня только позабавил,

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

IB>Ты хоть читал этот Vote? Или ты опять начинаешь вольной трактовкой заниматься? "... The Entity Framework encourages the Anemic Domain Model anti-pattern ...", и прочая риторика направленная на то, что стройный стиль — это отстой, а жирный — рулит всегда, "как подтверджает наш многолетнйи опыт", ага.


Так это единстванная критика. Назвали антипаттерном. Письмо про бузину, а дядьку алкашом обозвали.

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


МС не пошел другим путем. МС всеголишь не реализовал LL, притягивать сюда за уши противостояние anemic/rich можно, но после притягивания надо всетаки закрепить какойнить весомой ссылкой на источник близкий к архитекторам EF.

Z>>Непонятно почему ты не затрудняешь себя аргументацией выдвинутого тобой(?) тезиса:

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

Z>>Непонятно почему критикуя rich model ты приводишь в пример ActiveRecord:

Z>>

Если, следуя логике "жирной" модели, класс с персистентными данными оборудован методом .Save(), сохраняющим данные в БД

IB>Ок, понесись по третьему кругу: Потому что метод Save(), в данном случае, ничем не отличается от метода Calculate(), так просто нагляднее.

Ага, всеглишь небольшая подмена понятий метод из слоя доступка к данным и метод из слоя бизенс логики в данном случае ничем не отличаются. Только пример нагляднее, только не имеет он отношения к проблемам rich model. Ты либо не делаешь разницы между rich model и active record либо пытаешься запутать читателя.

Z>>Непонятно почему отсутствие возможности LL объявляется провокацией проектировать anemic model (на самом деле оно просто лишает возможностей трекинга).

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

А как ты для себя объясняешь факт того, что EF провоцирует проектировать anemic model? Просто поверил на слово?

IB>С другой стороны, ты определенно споришь совсем не с тем, что я написал, а с какой-то вывернутой версией, где я затрудняюсь даже воспроизвести логику, которой ты руководствовался, придумывая за меня аргументы.


Видишь ли, ты не утруждаешь себя аргументами.

Проблема в том, что в "жирной" модели, еще на этапе проектирования приложения нужно не просто обозначить ничего не обязывающую связь один ко многим, между заказом и продуктами в него входящими, а явно сказать, что коллекция объектов OrderItems принадлежит объекту Order


Почему нужно?
Это проблема трекинга, она может быть как в anemic так и в rich model. Можно делать rich без трекинга и anemic с ним. Этой проблеме посвящены три абзаца критикующие rich model.

откуда взят реально революционный для меня тезис?

- Single Responsibility Principle (SRP). Хранение данных в классе — это уже одна, вполне самостоятельная обязанность, добавление другой логики в класс приводит к нарущению этого принципа. Таким образом, вынос логики из класса производится в строгом соответствии SRP.

Я один сомневаюсь в этом утверждении?

IB>Выводы из всего этого можно сделать следующие: Либо ты, всетаки, очень хочешь поговорить со мной на тему NHibernate и EF и ORM вообще, и таким сомнительным способом пытаешься вовлечь меня в это дело, ну не вопрос давай тогда откроем отдельный топик, так как к обсуждаемой теме это не имеет никакого отношения. Либо ты пытаешься рассказать мне, что я на самом деле имел ввиду, когда писал этот пост в блоге. В этом случае предлагаю дальнейшую дискуссию прекратить, за очевидной бесполезностью.


Нет. Мне не нравится некая каша в изложении и я ее критикую, а ты ищешь скрытые мотивы.

Зачем критикую? Может я что-то не так понимаю и мне тут впрявят мозги.

Я в курсе, что тебе нравятся структуры данных максимально повторяющие таблицы (простой мэппинг, отсутствие трекинга).
Я в курсе, что тебе нравится разделять логику обработки и сами данные (anemic модель).

Зачем недостатки трекинга и сложных мэппингов подавать как недостатки rich модели? У нее своих мало чтоли?
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[10]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 27.10.08 17:26
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Приятнуто за уши, называть Ayende автором NH как-то странно.

Z> Причины: NHibernate всеголишь порт Hibernate,
А у порта авторства — нет? Забавно... Код из воздуха появляется, святым байтом. =)

Z> идеологию они не определяют,

Я могу в третий раз повторить — мне плевать на идеологию как гибернейта, так и NH. Сколько можно объяснять, что не о них речь?
Если хочешь об этом поговорить — открывай отдельный топик.

Z>авторство тут некорректный термин.

А какой корректный?

Z> Подписал документ он аж 29ым, налицо передергивание.

Какая разница каким он его подписал? Подписал, значит согласен и поддерживает.

Z>Подача:

Z>

Сторонники "Жирной" (Rich) модели (к числу которых относятся и разработчики NHibernate), моментально нашли фатальный недостаток в EF — он провоцирует работать с данными "Стройном" (Anemic) стиле, и принялись с усердием обличать в этом EF...

И где не соответствие?
"Петиция" обвиняет EF в провокации в стройном стиле? Обвиняет, факт. Разработчики NH согласны с этим обвинением? Согласны, факт.
Что тебя неустраивает?

Z> На самом деле там полно другой критики по существу.

На самом деле по существу там критики нет. Документ на редкость истеричный и все там притянуто зауши. Собственно единственные два пункта по которым вообще имеет смысл дискутировать — это как раз Anemic vs Rich и LL.

Z>Для красного словца же выдумана терминология в стиле плохой/хороший.

Нда.. Это в пику Фаулеровским Rich/Anemic, которые имеют соответствующий оттенок в английском, так что претензии опять не ко мне.

Z>Т.е. ты забыл про кого ты писал и пришлось таки поискать среди авторов разработчика NH?

Я помню, что в составлении этого послания принимал кто-то из NH, им еще активно размахивали как флагом, типа "вон какие люди с нами", я не обязан их помнить поименно.

Z>Так это единстванная критика.

Ты точно этот документ читал? Один пункт возражений из пяти является прямой и непрекрытой пропагандой жирной модели, не замечать этого можно только сознательно искажая. Эта же мысль повторяется и в различных блогах комментаторов, только ты почему-то считаешь по другому, ну, твое право конечно, только какой смысл это здесь обсуждать?

Z>МС не пошел другим путем. МС всеголишь не реализовал LL, притягивать сюда за уши противостояние anemic/rich можно, но после притягивания надо всетаки закрепить какойнить весомой ссылкой на источник близкий к архитекторам EF.

Еще раз тебе говорю — не ко мне претензия. Я одного не понимаю, ты сознательно игнорируешь то что тебе пишут, или просто не читаешь?
То что MS пошел другим путем — это не мое мнение, а мнение авторов петиции, с ними вот и спорь.

Z>Ага, всеглишь небольшая подмена понятий метод из слоя доступка к данным и метод из слоя бизенс логики в данном случае ничем не отличаются.

Так "не отличаются" или "подмена понятий"?

Z>А как ты для себя объясняешь факт того, что EF провоцирует проектировать anemic model? Просто поверил на слово?

Он и в третий раз пошел за елкой. Понимаешь, я не собираюсь объяснять этот факт, мне не интересно откуда его достали. Факт не мой, я тебе устал уже об этом писать. Я его просто взял и прокомментировал, так как считаю нужным. Как я к нему отношусь — это другой вопрос.

Z>Видишь ли, ты не утруждаешь себя аргументами.

Что аргументировать-то? Твои попытки убедить меня в том, что я на самом деле имел ввиду?

Z>Мне не нравится некая каша в изложении и я ее критикую, а ты ищешь скрытые мотивы.

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

Z>Зачем критикую? Может я что-то не так понимаю и мне тут впрявят мозги.

У тебя странная критика, ты уже на протяжении нескольких сообщений занимаешься прикладной демагогией, обсуждая не сколько аргументацию, сколько мою манеру изложения. По делу было только пара вопросов, на них, если позволишь, отвечу отдельно.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[10]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 27.10.08 17:26
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>Это проблема трекинга, она может быть как в anemic так и в rich model. Можно делать rich без трекинга и anemic с ним. Этой проблеме посвящены три абзаца критикующие rich model.

Z>Зачем недостатки трекинга и сложных мэппингов подавать как недостатки rich модели? У нее своих мало чтоли?
Совершенно верно. Здесь я действительно допустил промашку в изложении, не раскрыв до конца что же именно я понимаю под жирной моделью.
Формально, таки да то что ты называешь "теркингом" может быть как в стройной модели, так и может быть жирная модель без "трекинга". Но на практике, и в многочисленных примерах, я не встречал жирной модели без "трекинга", а про стройную с "трекингом" только упоминания слышал.
Так что в целом да, первая часть поста была посвящена критике организации объектов с необходимостью "трекинга", что по моему мнению является неотъемлимым атрибутом жирной модели, хотя при желании, действительно, можно родить жирную модель без оного.

Z>откуда взят реально революционный для меня тезис?

Революционного в нем ничего нет.

Z>Я один сомневаюсь в этом утверждении?

Есть конечно и другие, так что в целом ты в этом заблуждении не одинок..
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[11]: роль ООП при работе с данными
От: Ziaw Россия  
Дата: 28.10.08 12:31
Оценка: 8 (1) +1
Здравствуйте, IB, Вы писали:

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


Я рожал обе Rich модель без трекинга хорошо себя показала в десктоп приложении, anemic с ограниченным применением трекинга пока неплох в трехзвенке.

Говорю пока, т.к. до внедрения она еще не дошла. Но за полтора года проектирования и разработки серьезных нареканий не вызвала.
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[11]: роль ООП при работе с данными
От: Torvin  
Дата: 28.10.08 19:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

T>>для строк immutable — это эмуляция поведения value-типа. для сложных объектов (т.е. состоящих из нескольких полей) я себе этого не представляю
S>Для улучшения представлений рекомендую познакомиться с DateTime.
S>Ты в курсе того, что в Яве приходится со страшной силой приседать, чтобы только не дать стороннему коду надругаться над person.GetBirthday() произвольным образом? Это только потому, что даты в яве — mutable.
S>Практика применения показывает, что никаких трудностей со сложными датами у программистов не возникает.
давайте подумаем внимательно вместе. во-первых дата — это не несколько полей а одно — количество тиков прошедших с некоторой даты X. но это не важно. важно то, что "во-вторых"
во-вторых, посмотрим почему для даты уместо immutable-поведение? скажем, поменяем дате год. теперь у нас два объекта, скажем 18.10.2008 и 18.10.1937
это разные даты? да! точно такая же логика и со строками
а теперь поменяем имя проекту. если проект immutable, то у нас тоже будет 2 разные сущности. но действительно ли это разные объекты? нет. это тот же самый проект, просто пользователь исправил опечатку которую допустил при его создании. чувствуете разницу?

разве я не прав?..

PS
я не знаю как там в джаве, никогда не писал, но уверен что все решается в духе
return _birthday.Clone();
или там
return new DateTime(_birthday.GetTicks());
это конечно не есть гуд, но мы сейчас не о проблемах в джаве
Re[11]: роль ООП при работе с данными
От: Torvin  
Дата: 28.10.08 19:30
Оценка:
Здравствуйте, IB, Вы писали:

T>>для сложных объектов (т.е. состоящих из нескольких полей) я себе этого не представляю

IB>Ну и напрасно, имеет смысл представить. От количества полей тут ничего не зависит.
если вас не затруднит — прочтите пожалуйста соседнее мое сообщение по этому поводу Sinclair'у

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

IB>На лиспе, к слову GC в .Net написан, так что не надо про сферических коней.. )
на сколько я помню, на лиспе писался только первый вариант GC. и, как сказал автор, "потому что у лиспа такой прикольный синтаксис!" (к сожалению не могу найти ссылку на источник с цитатой)
кроме того, GC это просто реализация некоего алгоритма. логика известна, структуры данных известны, и ничего никогда не поменяется. хоть на голом Си пиши и вылизывай до бесконечности профайлером. и практически плевать на maintainability
сферический конь и есть


T>> просто в нашем случае по крайней мере известно где искать грабли

IB>Я предпочитаю, чтобы за меня их находил компилятор.
T>>любому нормальному человеку, пишущему код на основе жирной модели никогда не придет в голову делать поле ID writable. потому что в этом нет никакой необходимости
IB>Ты сам себе противоречишь. Почему в одном случае ID обязательно делать изменяемым, чтобы избежать каких-то мифических проблем с immutable, а в другом этого делать нет никакой необходимости?

похоже мы друг-друга не понимаем. приведите пожалуйста на всякий случай свое определение термина immutable. я лично считаю что объект immutable в том случае, если после создания его поля никогда не меняются. ни "изнутри" объекта, ни снаружи какими-то "менеджерами". а Вы?
Re[12]: роль ООП при работе с данными
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 28.10.08 19:45
Оценка:
Здравствуйте, Torvin, Вы писали:

T>во-вторых, посмотрим почему для даты уместо immutable-поведение? скажем, поменяем дате год. теперь у нас два объекта, скажем 18.10.2008 и 18.10.1937

T>это разные даты? да! точно такая же логика и со строками
T>а теперь поменяем имя проекту. если проект immutable, то у нас тоже будет 2 разные сущности. но действительно ли это разные объекты? нет. это тот же самый проект, просто пользователь исправил опечатку которую допустил при его создании. чувствуете разницу?
Неубедительно. Почему это один объект с точки зрения программы?
Re[13]: роль ООП при работе с данными
От: Torvin  
Дата: 28.10.08 19:53
Оценка:
Здравствуйте, gandjustas, Вы писали:

T>>во-вторых, посмотрим почему для даты уместо immutable-поведение? скажем, поменяем дате год. теперь у нас два объекта, скажем 18.10.2008 и 18.10.1937

T>>это разные даты? да! точно такая же логика и со строками
T>>а теперь поменяем имя проекту. если проект immutable, то у нас тоже будет 2 разные сущности. но действительно ли это разные объекты? нет. это тот же самый проект, просто пользователь исправил опечатку которую допустил при его создании. чувствуете разницу?
G>Неубедительно. Почему это один объект с точки зрения программы?
с точки зрения программы он может быть и одним и не одним. как напишем так и будет. я пытаюсь заставить задаться вопросом почему стоит делать так а не иначе. вопрос целесообразности, понимаете?
почему по-вашему DateTime и String являются immutable в .NET (кстати один из них ref- а другой value-type, и это не прихоть разработчиков, на это есть причина, но мы сейчас не об этом). почему, например, какой-нибудь захудалый System.Windows.Forms.Timer не immutable?.....
Re[12]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 28.10.08 22:07
Оценка:
Здравствуйте, Torvin, Вы писали:

T>на сколько я помню, на лиспе писался только первый вариант GC.

Совершенно верно, но сути дела это не меняет.

T>сферический конь и есть

Я правильно понимаю, что ты считаешь, что функциональные языки настолько акодемичны, что на них нельзя решить реальные прикладные задачи?

T> я лично считаю что объект immutable в том случае, если после создания его поля никогда не меняются.

Как это определение влияет на то, что в одном случае ID можно сделать readonly, а в другом почему-то нельзя?
Мы уже победили, просто это еще не так заметно...
Re[12]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 28.10.08 22:40
Оценка:
Здравствуйте, Torvin, Вы писали:

T> но действительно ли это разные объекты? нет.

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

T> это тот же самый проект, просто пользователь исправил опечатку которую допустил при его создании. чувствуете разницу?

Понимаешь, есть такой нюанс. Скажем, для финансовой отчетности важно знать, что когда этот проект использовался до исправления, то он назывался так, а когда после, то по другому. Чувствуешь разницу?
В сознании пользователя это может быть и один объект, а с точки зрения приложения очень удобно иметь доступ ко всем его предыдущим состояниям, как к отдельным самостоятельным объектам.

T>разве я не прав?..

Нет.. )
Мы уже победили, просто это еще не так заметно...
Re[14]: роль ООП при работе с данными
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.10.08 05:18
Оценка:
Здравствуйте, Torvin, Вы писали:

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


T>>>во-вторых, посмотрим почему для даты уместо immutable-поведение? скажем, поменяем дате год. теперь у нас два объекта, скажем 18.10.2008 и 18.10.1937

T>>>это разные даты? да! точно такая же логика и со строками
T>>>а теперь поменяем имя проекту. если проект immutable, то у нас тоже будет 2 разные сущности. но действительно ли это разные объекты? нет. это тот же самый проект, просто пользователь исправил опечатку которую допустил при его создании. чувствуете разницу?
G>>Неубедительно. Почему это один объект с точки зрения программы?
T>с точки зрения программы он может быть и одним и не одним. как напишем так и будет. я пытаюсь заставить задаться вопросом почему стоит делать так а не иначе. вопрос целесообразности, понимаете?
Понимаю. Также понимаю что в случае разных объектов после изменения одного поля гораздо проще обеспечить optimistic concurrency.

T>почему по-вашему DateTime и String являются immutable в .NET (кстати один из них ref- а другой value-type, и это не прихоть разработчиков, на это есть причина, но мы сейчас не об этом). почему, например, какой-нибудь захудалый System.Windows.Forms.Timer не immutable?.....

Timer — внешний ресурс, как файл или соединение с БД. Хотя и его можно было сделать immutable но такие решения только усложняют использование.
Re: роль ООП при работе с данными
От: Аноним  
Дата: 29.10.08 13:43
Оценка: +1 -1
Здравствуйте, QrystaL, Вы писали:

QL>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686


QL>Кто что скажет?


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

QL>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686

QL>Кто что скажет?

По-моему, происходит массовое непонимание/недопонимание друг друга. Одни (в том числе автор оригинальной статьи) воспринимает анемичную модель как "вааще анемичную" — POD-объекты (максимум — аксессоры к ним), и не более. Его противники считают, что объекты рассматриваемой предметной области — это несколько не то, что лежит в БД; код, который обеспечивает соответствие (вернее, восстанавливает потерянное identity при преобразованиях OOP<->Relation) обязан быть, и его присутствие в модели предметной области не определяет однозначно, что это — уже жирная модель.

Поясню. Сторонники анемичной модели настаивают на следующей схеме:
DB <-> Data Objects (anemic model) <-> Rich OO Model + Services.

В то время, как "жирная" модель хочет обойтись такой схемой:
DB <-> Rich Domain Model + Services (optionally).

При этом в первом случае вы руками пишете код, который обеспечивает соответвие identity, равномерно распределяя его по бизнес-логике (пример — ручной lazy loading и коллекции), во втором — к этому привлекаются механизмы OR/M (как, например, в NHibernate).

При этом как-то незаметно подменяется спор о Anemic .vs. Rich спором о том, кто правильнее реализует Domain Model в частном случае применения в OR/M, и из этого делаются неаргументированные выводы в пользу EF. (И причем здесь ООП?). Аналогично подменяется понятие OOP Data на Relation Data, которые, мягко говоря, далеки от ООП.

И мой взмах мечом в холиваре — EF не способствует написанию в анемичном стиле, он просто не способен полноценно поддерживать "жирную" модель.
Спасибо.
Re[13]: роль ООП при работе с данными
От: Torvin  
Дата: 03.11.08 17:53
Оценка:
IB>Понимаешь, есть такой нюанс. Скажем, для финансовой отчетности важно знать, что когда этот проект использовался до исправления, то он назывался так, а когда после, то по другому. Чувствуешь разницу?
IB>В сознании пользователя это может быть и один объект, а с точки зрения приложения очень удобно иметь доступ ко всем его предыдущим состояниям, как к отдельным самостоятельным объектам.
ну это очччень частный случай. даже если он встречается Вам чаще чем другие случаи — это еще не дает повод клепать все подряд объекты как 'immutable' — "авось пригодится"

G>Понимаю. Также понимаю что в случае разных объектов после изменения одного поля гораздо проще обеспечить optimistic concurrency.

действительно. поэтому в разных дата-сессиях объекты и должны быть разными. но в одной датасессии?!... какая-такая там concurrency?
Re[13]: роль ООП при работе с данными
От: Torvin  
Дата: 03.11.08 18:00
Оценка:
вдогонку

T>сферический конь и есть

IB>Я правильно понимаю, что ты считаешь, что функциональные языки настолько акодемичны, что на них нельзя решить реальные прикладные задачи?
одно из другого не следует, и я не особо силен в области функциональных языков.
просто пример с реализацией GC на Lisp "потому что у него прикольный синтаксис" (с) явно является плохим аргументом в нашей дискуссии
Re[9]: роль ООП при работе с данными
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 14.11.08 11:14
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Это, конечно, не единственный способ построить MVP архитектуру, но в принципе вполне жизнеспособный. Поясняю: в этом подходе данные достаются из SQL сервера за один (1) прием. Есть гарантия того, что никакая ленивая зараза не потащит какой-то хвост из базы в момент, когда уже Render поехал. Далее, нет никакого кэша объектов, который живет своей жизнью, жрет память и требует синхронизации. Всё, мы датасет забрали, теперь можно отпустить SQL сервер заниматься другой полезной работой. Импульсный режим для серверов — это самый сенокос.

У меня именно по варианту начальника (Re[7]: роль ООП при работе с данными
Автор: Mmmaloy
Дата: 21.10.08
) работает система, в которой вполне себе анемичные модели, но при этом вместо Datasets задействован NHibernate, частично ленивая загрузка (проксирование) и несколько кешей (Identity Map & Query Cache). NHibernate позволяет построить как anemic, так rich модели. Не вижу озвученного автором антогонизма NHibernate и Anemic model. Если же Entity Framework умеет только первый подход (anemic), то высказывание о недостатках NHibernate вначале статьи и о достоинствах EF в конце статьи, мне кажется, автору стоило озвучить с другим акцентом.

S>Теперь у нас, значит, поехала трансформация. В чем начальник прав? С тем, что редкий databound контрол в aspx сравнится по скорострельности отплевывания форматированного аутпута со старым добрым откомпилированным XSLT. Я надеюсь, все в курсе, что текстовый XSLT сначала парсится, потом по нему генерируется MSIL код, который затем обрабатывается джитом, и в итоге мы имеем самый что ни на есть нативный код, который шарашит по твоему XML как казак по степи?

Насколько знаю, старый добрый XSLT в .NET — XslTransform — вовсе не компилированный, а компилируется в MSIL и соответственно оптимизируется JIT-ом новый — XslCompiledTransform.
Re: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 22.11.08 22:00
Оценка:
Здравствуйте, QrystaL, Вы писали:

QL>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686

QL>Кто что скажет?

А мне не понравилась статья. Это называется взять одно архитектурное решение и довести его до абсурда. После прочтения статьи вообще складывается ощущение, будто бы тот же lazy loading в жирной модели вообще прикручивают только для того, чтобы не оставлять пустыми всякие OrderItems, когда они не заполняются т.к. не нужны. Так если они не нужны зачем вообще lazy loading? Почему бы не сделать так:

class CustomerFrame
{
  int Id { get; }
  string Name { get; set; }
}

class Customer : CustomerFrame
{
  OrderItemList Orders { get; }
}


Да и вообще, честно, вся эта проблема жирной версус тонкой модели кажется мне немного надуманной. У ООП есть одна фишка, к-я там вскользь упомянута, называется инкапсуляция. Инкапсуляция означает, что клиентскому коду должно быть насрать, что там конкретно происходит, когда вызывается какой-нибудь Order.Save.
Не исключено, конечно, что кто-нибудь — как это живописно описывается в статье — там прям внутри одного метода и логику БД описывает и сериализацию в ХМЛ да еще и сетевую передачу вдобавок. Но тут наверное не жирная модель виновата, это уже с мозгом что-то.
Кто мешает сделать так:

class Order<T> where T : IPersistanceModel
{
  void Save()
  {
    persistanceModel.Save(this);
  }
}

Order<Database> order = ...
order.Save();


Или даже не выносить эту самую persistance model в интерфейс, если эти не нужно. Клиентский код при это вообще не будет знать, жирно там или не жирно. А все фишки жирной модели и "более объектно-ориентированного подхода" — налицо.
Re[2]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.11.08 07:02
Оценка: 19 (5) +2
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Да и вообще, честно, вся эта проблема жирной версус тонкой модели кажется мне немного надуманной. У ООП есть одна фишка, к-я там вскользь упомянута, называется инкапсуляция. Инкапсуляция означает, что клиентскому коду должно быть насрать, что там конкретно происходит, когда вызывается какой-нибудь Order.Save.
Это категорическое заблуждение. Проблема ООП именно в том, что велик риск сделать неудачную инкапсуляцию.
Дело в том, что если клиентский код обращается, к примеру, к Order.Items, то автору этого кода в первый момент могут показаться неинтересными подробности того, что там происходит "за кадром".
Но во второй момент, автор кода обнаружит, что есть принципиальная разница между предварительно загруженными и доступными Order.Items, и спрятанным "благодаря инкапсуляции" обращением к SQL серверу за наполнением этой коллекции.

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

Проблема — в том, что обращение Order.Items прячет от клиента важную семантику.

К примеру, все коннекторы к СУБД, применяемые в дотнете, поддерживают асинхронную модель исполнения. Это означает, что умный клиентский код может запросить недостающие данные, и пока они готовятся, заниматься своими делами.

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

Далее, у клиентского кода, который делает вызов Order.Items нет никакого способа сообщить инфраструктуре подробности своих пожеланий. Он не может отменить запрос, если он занял больше времени, чем ожидалось. Он не может внятно объяснить, важно ли ему обеспечить транзакционную целостность между Order и Items, или можно отдать текущее состояние Items, а не то, которое было в момент загрузки Order. Он не может объяснить, что уже однажды загружал Items для этого Order, и теперь ему нужно обновить их, причем только в том случае, если хоть что-то поменялось.

Все эти полезные подробности, вытекающие из удаленного характера Items, скрыты за тупым геттером.
Некоторые из них можно получить, подергав за неочевидные настройки какого-то контекста. Изучение этих неочевидных настроек и составляет квалификацию опытного разработчика под Full-blown ORM. При этом некоторые из возможностей вообще остаются неизвестными даже для самых продвинутых разработчиков — к примеру, асинхронная модель исполнения.

Поэтому, продолжая твою терминологию, если клиентскому коду "насрать", то гарантированно получится "говно".
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 24.11.08 11:31
Оценка: +2 -1
Здравствуйте, Sinclair, Вы писали:

ВВ>>Да и вообще, честно, вся эта проблема жирной версус тонкой модели кажется мне немного надуманной. У ООП есть одна фишка, к-я там вскользь упомянута, называется инкапсуляция. Инкапсуляция означает, что клиентскому коду должно быть насрать, что там конкретно происходит, когда вызывается какой-нибудь Order.Save.

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

А еще велик риск сделать неудачную декомпозицию на сущности. Неудачную иерархию наследования и пр. Везде сплошные риски.
Я вообще-то комментаривал статью, в которой критика жирной модели строится по принципу — а вот смотрите, если мы напишем это мега-криво, то, блин, это ведь действительно будет криво.
С какого боку я должен внутри какого-нибудь Order.Save вхреначить разранородный код сериализации в ХМЛ, записи в БД и прочая — да еще сделать так, чтобы одно другому мешало? Почитав автора блога можно сделать вывод, что это особенности жирной модели. В действительности это не так.
Я привел пример реализации которая не обладает большей частью упомянутых в статье недостатков и позволяет легко модицифицировать алгоритмы, без какого-то там влияния одного на другое.

S>Дело в том, что если клиентский код обращается, к примеру, к Order.Items, то автору этого кода в первый момент могут показаться неинтересными подробности того, что там происходит "за кадром".

S>Но во второй момент, автор кода обнаружит, что есть принципиальная разница между предварительно загруженными и доступными Order.Items, и спрятанным "благодаря инкапсуляции" обращением к SQL серверу за наполнением этой коллекции.
S>Дело даже не в том, сколько времени займет эта операция. Проблемы стоимости операций и сигнатур методов обсуждались еще у Страуструпа, в доисторические времена.
S>Проблема — в том, что обращение Order.Items прячет от клиента важную семантику.

Т.е. сейчас речь уже идет о том, что ленивая загрузка в Order.Items — это плохо? Или что? Я где-то писал, что необходимо делать ленивую загрузку?
Ленивая загрузка или нужна или не нужна. Никто не заставляет "прятать" от клиента важную семантику при проектировании жирной модели. И при тонкой модели тоже можно много чего запрятать, было бы желание.
Если нужна коллекция Items — возвращаем класс Order, в котором она содержится. Если не нужна — класс OrderFrame, в котором ее нет.
Также как и автор статьи по ссылке, ты пытаешь жирной модели приписать недостатки, которых у нее нет. Это недостатки конкретного подхода к проектированию жирной модели.

S>К примеру, все коннекторы к СУБД, применяемые в дотнете, поддерживают асинхронную модель исполнения. Это означает, что умный клиентский код может запросить недостающие данные, и пока они готовятся, заниматься своими делами.

S>В применении к Order.Items это означает, что эта "инкапсуляция" вынуждает клиентский код выполнять ряд запросов последовательно, блокируясь на время ожидания. Что, естественно, ухудшает производительность.

А что хочет клиентский код? Получить синхронно Order и асинхронно какие-то внутренние Items? Кто мешает реализовать это в жирной модели? И почему жирная модель должна полагаться на какие-то непонятно ленивые св-ва типа Items? Например, класс Order может предоставлять метол для асинхронной загрузки своих данных на основе данных OrderFrame.

И заметь, я про это ничего не писал. Я сказал, что клиентскому коду должно быть насрать на то, что происходит при вызове Order.Save — выполняется ли код внутри Order, делегирует ли вызов и пр. Это утверждение было моментально перенесено на что-то другое, с чем можно удобно поспорить. Не конструктивно, товарищ.

S>Далее, у клиентского кода, который делает вызов Order.Items нет никакого способа сообщить инфраструктуре подробности своих пожеланий. Он не может отменить запрос, если он занял больше времени, чем ожидалось. Он не может внятно объяснить, важно ли ему обеспечить транзакционную целостность между Order и Items, или можно отдать текущее состояние Items, а не то, которое было в момент загрузки Order. Он не может объяснить, что уже однажды загружал Items для этого Order, и теперь ему нужно обновить их, причем только в том случае, если хоть что-то поменялось.

S>Все эти полезные подробности, вытекающие из удаленного характера Items, скрыты за тупым геттером.

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

S>Некоторые из них можно получить, подергав за неочевидные настройки какого-то контекста. Изучение этих неочевидных настроек и составляет квалификацию опытного разработчика под Full-blown ORM. При этом некоторые из возможностей вообще остаются неизвестными даже для самых продвинутых разработчиков — к примеру, асинхронная модель исполнения.

S>Поэтому, продолжая твою терминологию, если клиентскому коду "насрать", то гарантированно получится "говно".

Да, очередная попытка вырвать фразу из контекста и сделать на основе нее далеко идущие выводы. Низачет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[4]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.11.08 12:02
Оценка: 1 (1) +1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>А еще велик риск сделать неудачную декомпозицию на сущности. Неудачную иерархию наследования и пр. Везде сплошные риски.

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

ВВ>С какого боку я должен внутри какого-нибудь Order.Save вхреначить разранородный код сериализации в ХМЛ, записи в БД и прочая — да еще сделать так, чтобы одно другому мешало? Почитав автора блога можно сделать вывод, что это особенности жирной модели. В действительности это не так.

Прочитав автора блога, можно сделать вывод, что что бы ты ни вхреначил в метод Order.Save — это будет криво.
ВВ>Я привел пример реализации которая не обладает большей частью упомянутых в статье недостатков и позволяет легко модицифицировать алгоритмы, без какого-то там влияния одного на другое.
Да ну правда что ли? Приведенный тобой пример ровно и обладает "большей частью упомянутых в статье недостатков".
В частности, Order начинает зависеть от IPersistenceModel. Я уж молчу про то, что в твоем коде как-то ловко сделан переход от типа к экземпляру, то есть механика скармливания в Order конкретного экземпляра Database почему-то оставлена за кадром.

ВВ>Т.е. сейчас речь уже идет о том, что ленивая загрузка в Order.Items — это плохо?

Да.
ВВ>Или что? Я где-то писал, что необходимо делать ленивую загрузку?

ВВ>Если нужна коллекция Items — возвращаем класс Order, в котором она содержится. Если не нужна — класс OrderFrame, в котором ее нет.

Ты приводишь вырожденный пример, где есть два класса, причем вроде бы в тонкой модели. Фишка в том, что в жизни их будет не 2, а 2-в-степени-количество-ленивых-свойств.

ВВ>А что хочет клиентский код? Получить синхронно Order и асинхронно какие-то внутренние Items? Кто мешает реализовать это в жирной модели?

Никто не мешает. Но в жирной модели мы перемешиваем логику управления загрузкой с бизнес-логикой.
ВВ>И почему жирная модель должна полагаться на какие-то непонятно ленивые св-ва типа Items? Например, класс Order может предоставлять метол для асинхронной загрузки своих данных на основе данных OrderFrame.
О, это уже вообще запредельный ахтунг.

ВВ>И заметь, я про это ничего не писал. Я сказал, что клиентскому коду должно быть насрать на то, что происходит при вызове Order.Save — выполняется ли код внутри Order, делегирует ли вызов и пр. Это утверждение было моментально перенесено на что-то другое, с чем можно удобно поспорить.

Ок, это утверждение тоже, мягко говоря, неверно.
Потому, что у клиентского кода должна быть, к примеру, некоторая уверенность в том, что Order.Save запишет ордер туда же, куда Customer.Save только что записала кастомера.
Инкапсуляция здесь только вредит — какова семантика этого Save? В контексте какой транзакции будут проведены изменения? Почему объект доменной модели обязан знать про транзакции и контексты? Зачем нам вообще всовывать во все доменные объекты Save, который еще и должен быть реализован одинаковым образом — делегировать вызов в соответствующий сервис? Это чему помогает? Если сильно чешется писать именно "горшочек.Вари()" — используйте Extension Methods.

ВВ>Пишите тривиальную реализацию свойств, и все будет прекрасно.

То есть применять анемичную модель? Я — согласен.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: роль ООП при работе с данными
От: Aikin Беларусь kavaleu.ru
Дата: 24.11.08 12:20
Оценка:
Здравствуйте, Sinclair, Вы писали:

ВВ>>А что хочет клиентский код? Получить синхронно Order и асинхронно какие-то внутренние Items? Кто мешает реализовать это в жирной модели?

S>В частности, Order начинает зависеть от IPersistenceModel. Я уж молчу про то, что в твоем коде как-то ловко сделан переход от типа к экземпляру, то есть механика скармливания в Order конкретного экземпляра Database почему-то оставлена за кадром.
S>Никто не мешает. Но в жирной модели мы перемешиваем логику управления загрузкой с бизнес-логикой.
Никто ничего не перемешивает. Вполне возможно совместить Persistance Ignorance и Lasy Load -- проксирование ведь никто не отменял. Я даже как-то ваял пример
Автор: Aikin
Дата: 23.05.08
.

ВВ>>И почему жирная модель должна полагаться на какие-то непонятно ленивые св-ва типа Items? Например, класс Order может предоставлять метол для асинхронной загрузки своих данных на основе данных OrderFrame.

S>О, это уже вообще запредельный ахтунг.
+1
Re[5]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 24.11.08 12:39
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Прочитав автора блога, можно сделать вывод, что что бы ты ни вхреначил в метод Order.Save — это будет криво.

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

Какими конкретно? Единственный недостаток — проблемы в распределенном приложении, в котором, собственно, говоря чем тоньще интерфейс тем лучше.

S>В частности, Order начинает зависеть от IPersistenceModel.


Будет. На то это и жирная модель. Причем никто не заставляет выносить IPersistenceModel в интерфейс, если это не нужно.
Вот только модификация алгоритмов будет происходить также легко как и в случае, что с тонкой моделью — что ты сам так долго расписывал в качестве критики жирной модели.

S>Я уж молчу про то, что в твоем коде как-то ловко сделан переход от типа к экземпляру, то есть механика скармливания в Order конкретного экземпляра Database почему-то оставлена за кадром.


Перед от "типа к экземпляру" — деталь реализации, неважная в данном случае.

ВВ>>Т.е. сейчас речь уже идет о том, что ленивая загрузка в Order.Items — это плохо?

S>Да.
ВВ>>Или что? Я где-то писал, что необходимо делать ленивую загрузку?
ВВ>>Если нужна коллекция Items — возвращаем класс Order, в котором она содержится. Если не нужна — класс OrderFrame, в котором ее нет.
S>Ты приводишь вырожденный пример, где есть два класса, причем вроде бы в тонкой модели. Фишка в том, что в жизни их будет не 2, а 2-в-степени-количество-ленивых-свойств.

А сколько обычно ленивых свойств бывает в жирной модели? 100, 1000? Значит будет столько и классов. Каждое ленивое свойство прячет за собой фактически связь между сущностями. И логично, что такая связь должна быть представлена в виде сущности.
А заодно стоит отличать пример и собственно описание подхода, которое за этим примером кроется. Если связей много, кто мешает сделать так:

class OneToManyRelation<TParent,TChild>
{
    TParent Parent { get; }
    
    List<TChild> Children { get; }
}


Да и если даже наваять тысячи классов, то вся проблема будет только в количестве классов. Других проблем не будет.

ВВ>>А что хочет клиентский код? Получить синхронно Order и асинхронно какие-то внутренние Items? Кто мешает реализовать это в жирной модели?

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

А ты не перемешивай. И причем тут вообще жирная модель? В тонкой модели в каком-нибудь OrderService ты можешь с таким же успехом перешивать бизнес-логику с логикой загрузки.

ВВ>>И почему жирная модель должна полагаться на какие-то непонятно ленивые св-ва типа Items? Например, класс Order может предоставлять метол для асинхронной загрузки своих данных на основе данных OrderFrame.

S>О, это уже вообще запредельный ахтунг.

Если развить пример, то я не вижу никакого ахтунга:

OneToManyRelation<TParent,TChild> CreateOneToManyRelation<Order,OrderItem>(myOrder order);

ВВ>>И заметь, я про это ничего не писал. Я сказал, что клиентскому коду должно быть насрать на то, что происходит при вызове Order.Save — выполняется ли код внутри Order, делегирует ли вызов и пр. Это утверждение было моментально перенесено на что-то другое, с чем можно удобно поспорить.

S>Ок, это утверждение тоже, мягко говоря, неверно.

Неверно то, что клиентский код не должен знать как именно происходит сохранение?

S>Потому, что у клиентского кода должна быть, к примеру, некоторая уверенность в том, что Order.Save запишет ордер туда же, куда Customer.Save только что записала кастомера.


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

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

S>Инкапсуляция здесь только вредит — какова семантика этого Save?


Такая же как и у OrderService.Save

S>В контексте какой транзакции будут проведены изменения?


А клиент в курсе про транзакции? Т.е. если завтра мы переделает персистенции с базы на ХМЛ — клиентский код в recycle bin?

S>Почему объект доменной модели обязан знать про транзакции и контексты?


Объект не знает. Знает IPersistanceModel.

S>Зачем нам вообще всовывать во все доменные объекты Save, который еще и должен быть реализован одинаковым образом — делегировать вызов в соответствующий сервис?


Это более "объектно ориентированно"
Я кстати нигде не устраивал противопоставление жирная vs. тонкая. Я лишь показываю, что критика жирной модели, которая приводится в блоге, по большей части несостоятельна.
Недостаток у жирной модели — один. Это жирный интерфейс.
У тонкой модель единственный плюс по сравнению с жирной моделью — это тонкий интерфейс.
И наоборот.
А то "клиентскому коду насрать", к которому ты так прицепился, относится именно к тому, что у нас жирная модель может быть построена по всем правилам тонкой модели вообще-то, с отдельными сервисами бизнес-логики, ДАЛа и проч. Бизнес-сущность будет лишь делать делегирование. При этом клиентский код будет в принципе не знать, как конкретно осуществляется эта операция — напрямую через бизнес-сущность или через отдельный сервис. И это действительно не должно касаться клиентского кода.

S>Это чему помогает?


Это чему-то мешает?

S>Если сильно чешется писать именно "горшочек.Вари()" — используйте Extension Methods.


Это часть контракта, зачем нужен extension methods.
Хотя... По большому счету это другой способ описания контракта.
Вот если оформить всю ф-ть в виде extension methods — это будет жирная или тонкая модель? Фактически — тонкая. Работать с ней клиент будет как с жирной. И соотв. прихожим к моему первоначальному утверждению, что вся эта проблема жирной версус тонкой модели является несколько надуманной.

ВВ>>Пишите тривиальную реализацию свойств, и все будет прекрасно.

S>То есть применять анемичную модель? Я — согласен.

Т.е. писать функции, которые предполагают однозначные действия. Если класс OrderService вместо очевидного Save будет содерждать метод FuckMySister — то вроде бы все у нас останется в рамках тонкой модели, однако вот смысл этого метода в отношении Order-a будет весьма и весьма туманен.
Или для тебя тривиальная реализация св-в равнозначна малохольной модели?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[6]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.11.08 13:18
Оценка: +1 -2
Здравствуйте, Воронков Василий, Вы писали:


S>>В частности, Order начинает зависеть от IPersistenceModel.


ВВ>Будет. На то это и жирная модель. Причем никто не заставляет выносить IPersistenceModel в интерфейс, если это не нужно.

И? Проблемы-то как раз в том, что невозможно вынести реализацию Order никуда, где нету конкретной PersistenceModel. Высокая связность, всё такое.

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

Не вижу никакой лёгкости. Где пример смены механизма Persistence? Где пример, когда один и тот же Order читается из Database, а сериализуется в XML?

ВВ>Перед от "типа к экземпляру" — деталь реализации, неважная в данном случае.

Ну конечно. Грязными подробностями лучше сразу пренебречь.

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


ВВ>А сколько обычно ленивых свойств бывает в жирной модели?

Обычно — штук десять.
ВВ>100, 1000? Значит будет столько и классов. Каждое ленивое свойство прячет за собой фактически связь между сущностями. И логично, что такая связь должна быть представлена в виде сущности.
Ты ничего не путаешь? Это будет 2^10 классов, то есть 1024. Не многовато ли?

ВВ>А заодно стоит отличать пример и собственно описание подхода, которое за этим примером кроется. Если связей много, кто мешает сделать так:


ВВ>
ВВ>class OneToManyRelation<TParent,TChild>
ВВ>{
ВВ>    TParent Parent { get; }
    
ВВ>    List<TChild> Children { get; }
ВВ>}
ВВ>

Отлично. Давайте теперь откажемся от типизации. Вместо Order.Client, Order.Manager и так далее у нас будет итерирование по Children.
Сomedy Club отдыхает.

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

Да уж, майнтенанс тысячи классов — это пренебрежимо малая проблема по сравнению с преимуществами толстой модели.

ВВ>А ты не перемешивай. И причем тут вообще жирная модель? В тонкой модели в каком-нибудь OrderService ты можешь с таким же успехом перешивать бизнес-логику с логикой загрузки.

А могу и не перемешивать. А у тебя — 100% перемешивание.

ВВ>Если развить пример, то я не вижу никакого ахтунга:

ВВ>OneToManyRelation<TParent,TChild> CreateOneToManyRelation<Order,OrderItem>(myOrder order);
Ахтунг продолжает нарастать. Это где у нас предполагается такой метод?

ВВ>Неверно то, что клиентский код не должен знать как именно происходит сохранение?

Неверно то, что клиентский код должен рассчитывать на волшебную сохраняемость ордера как объекта.

ВВ>Такая уверенность не исключает инкапсуляции.

Просто место для этой инкапсуляции нужно выбирать с умом.

ВВ>Кстати, может, стоить прояснять смысл последнего термина, а то, мне кажется, есть некоторое непонимание?

ВВ>Инкапсуляция предполагает скрытие деталей реализации, а не самого действия. При вызове Save клиентский код должен знать что именно и куда сохраняется, но ему должно быть по фиг как именно это происходит.
Совершенно верно. И мне совершенно непонятно, каким образом в предлагаемом тобой примере клиентский код понимает, куда именно мы сохраняемся!

S>>Инкапсуляция здесь только вредит — какова семантика этого Save?

ВВ>Такая же как и у OrderService.Save
Где гарантия?

S>>В контексте какой транзакции будут проведены изменения?

ВВ>А клиент в курсе про транзакции? Т.е. если завтра мы переделает персистенции с базы на ХМЛ — клиентский код в recycle bin?
Естественно в курсе. Напомню, что транзакции — часть существенной логики.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 24.11.08 13:44
Оценка: -1
Здравствуйте, Sinclair, Вы писали:

ВВ>>Будет. На то это и жирная модель. Причем никто не заставляет выносить IPersistenceModel в интерфейс, если это не нужно.

S>И? Проблемы-то как раз в том, что невозможно вынести реализацию Order никуда, где нету конкретной PersistenceModel. Высокая связность, всё такое.

А куда ее надо вынести? Преимущества легкой модели при распределенке — очевидны. Никто опять-таки не мешает, как уже было сказано, не выносить persistance model в интерфейс, что в случае с распределенкой только помешает и корректно описать ситуацию ее отсутствия.
Если нет конретной PersistenceModel, то это, наверное, значит, что нам нужны "тупо данные", не так ли? Это в любом случае не повод прикручивать ленивую инициализацию и пр., как это описывается в статье. Можно и вообще сделать так:

Order<T> : Order where T : IPersistanceModel

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

S>Не вижу никакой лёгкости. Где пример смены механизма Persistence?

А что по-твоему может вызвать проблему при смене Persistance. Сама сущность под конкретный persistance никак не заточена.

S>Где пример, когда один и тот же Order читается из Database, а сериализуется в XML?


А как эта проблема будет решаться в случае с тонкой моделью?
Ты пытаешься придумать для жирной модели проблемы, которых нет. Вернее, они есть в любой модели.
В данном конкретном случае — гибридная PersistanceModel.

ВВ>>Перед от "типа к экземпляру" — деталь реализации, неважная в данном случае.

S>Ну конечно. Грязными подробностями лучше сразу пренебречь.

И что в них грязного?
"Подробности" будут абсолютно такие же как и в случае с тонкой моделью — с той лишь разницей, что там вызывает метод GetOrder, здесь — конструктор класса.

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

ВВ>>А сколько обычно ленивых свойств бывает в жирной модели?
S>Обычно — штук десять.
ВВ>>100, 1000? Значит будет столько и классов. Каждое ленивое свойство прячет за собой фактически связь между сущностями. И логично, что такая связь должна быть представлена в виде сущности.
S>Ты ничего не путаешь? Это будет 2^10 классов, то есть 1024. Не многовато ли?

Я вообще-то имел в виду всего. Но ты видно опять нашел способ повеселиться.

ВВ>>А заодно стоит отличать пример и собственно описание подхода, которое за этим примером кроется. Если связей много, кто мешает сделать так:

ВВ>>
ВВ>>class OneToManyRelation<TParent,TChild>
ВВ>>{
ВВ>>    TParent Parent { get; }
ВВ>>    List<TChild> Children { get; }
ВВ>>}
ВВ>>

S>Отлично. Давайте теперь откажемся от типизации. Вместо Order.Client, Order.Manager и так далее у нас будет итерирование по Children.
S>Сomedy Club отдыхает.

Да, у тебя наверное точно будет "итерирование по Children".
Где тут отказ от типизации? Не вижу никакой проблемы в том, чтобы представить связь между сущностями в виде отдельной сущности, если так будет удобнее в конкретном случае.

ВВ>>А ты не перемешивай. И причем тут вообще жирная модель? В тонкой модели в каком-нибудь OrderService ты можешь с таким же успехом перешивать бизнес-логику с логикой загрузки.

S>А могу и не перемешивать. А у тебя — 100% перемешивание.

Обосновать можешь? У меня ровно те же самые возможности для разделения слоев, что и в тонкой модели.

ВВ>>Если развить пример, то я не вижу никакого ахтунга:

ВВ>>OneToManyRelation<TParent,TChild> CreateOneToManyRelation<Order,OrderItem>(myOrder order);
S>Ахтунг продолжает нарастать. Это где у нас предполагается такой метод?

Ну положим, есть класс Customer, у него есть отношение один-ко-многим к Order. Соответственно, мы имеем:

сам класс Customer, содержащий только данные по Customer и методы для работы только с данными Customer.
класс CustomerOrder —

CustomerOrderList CustomerOrder.GetOrdersFor(Customer customer)

— содержащий данные по взаимосвязи Customer->Order.

ВВ>>Неверно то, что клиентский код не должен знать как именно происходит сохранение?

S>Неверно то, что клиентский код должен рассчитывать на волшебную сохраняемость ордера как объекта.
ВВ>>Такая уверенность не исключает инкапсуляции.
S>Просто место для этой инкапсуляции нужно выбирать с умом.

Отлично, аргументы подменяем пустой демагогией.

ВВ>>Кстати, может, стоить прояснять смысл последнего термина, а то, мне кажется, есть некоторое непонимание?

ВВ>>Инкапсуляция предполагает скрытие деталей реализации, а не самого действия. При вызове Save клиентский код должен знать что именно и куда сохраняется, но ему должно быть по фиг как именно это происходит.
S>Совершенно верно. И мне совершенно непонятно, каким образом в предлагаемом тобой примере клиентский код понимает, куда именно мы сохраняемся!

А в случае с тонкой моделью как мы это понимаем?
Здесь — точно также.

S>>>Инкапсуляция здесь только вредит — какова семантика этого Save?

ВВ>>Такая же как и у OrderService.Save
S>Где гарантия?

Где гарантия, что OrderService.Save будет выполнять нужные нам действия, а?

S>>>В контексте какой транзакции будут проведены изменения?

ВВ>>А клиент в курсе про транзакции? Т.е. если завтра мы переделает персистенции с базы на ХМЛ — клиентский код в recycle bin?
S>Естественно в курсе. Напомню, что транзакции — часть существенной логики.

В таком случае никто не мешает предоставить доступ к модели транзакций и через жирную модель.
В жирной модели можно сделать все то же самое, что и в тонкой модели.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[2]: роль ООП при работе с данными
От: Sergey T. Украина http://overstore.codeplex.com
Дата: 25.11.08 09:14
Оценка:
> ...
Иногда создается такое впечатление, что единственное отличие "толстой" модели от "тонкой" — это ленивая загрузка. Причем обсуждаемая в контексте клиента. Хотя в большинстве случаев клиент удаленный, и "ленивую" загрузку явно практически не использует, а использует ДТО. Хотя возможно есть решения, когда объекты передачи данных тоже используют отложенную загрузку, однако они из области частных решений.

Как мне кажется, единственное объективное удобство тонкой модели в том, что она естественным образом ложится на сервис-ориентированную архитектуру, более того, она специально разрабатывается для такой архитектуры. Это позволяет при желании сэкономить на написании выделенного (отдельного) фасада системы.
There is no such thing as the perfect design.
Re[3]: роль ООП при работе с данными
От: Sergey T. Украина http://overstore.codeplex.com
Дата: 25.11.08 09:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>...

S>Проблема — в том, что обращение Order.Items прячет от клиента важную семантику.

S>К примеру, все коннекторы к СУБД, применяемые в дотнете, поддерживают асинхронную модель исполнения. Это означает, что умный клиентский код может запросить недостающие данные, и пока они готовятся, заниматься своими делами.


S>В применении к Order.Items это означает, что эта "инкапсуляция" вынуждает клиентский код выполнять ряд запросов последовательно, блокируясь на время ожидания. Что, естественно, ухудшает производительность.


S>Далее, у клиентского кода, который делает вызов Order.Items нет никакого способа сообщить инфраструктуре подробности своих пожеланий. Он не может отменить запрос, если он занял больше времени, чем ожидалось. Он не может внятно объяснить, важно ли ему обеспечить транзакционную целостность между Order и Items, или можно отдать текущее состояние Items, а не то, которое было в момент загрузки Order. Он не может объяснить, что уже однажды загружал Items для этого Order, и теперь ему нужно обновить их, причем только в том случае, если хоть что-то поменялось.


Если дела обстоят именно так, как Вы описываете, тогда действительно, делать Order.Items свойством — это ошибка проектирования.

S>Все эти полезные подробности, вытекающие из удаленного характера Items, скрыты за тупым геттером.

См. выше. Однако, рассмотрите также и ситуацию, когда Ордер.Айтемс — это именно свойство Ордер. С семантикой свойства. Ни один Айтем без заказа не существует. Удаляются они все вместе. Ну и так далее. Скажите, в таком случае отложенная загрузка — тоже плохо?

Кстати, почему это Вы говорите, что Items имеют "удаленный" характер? Отложенная загрузка ведь происходит на сервере приложения, а клиент получает уже сконструированные ДТО, в которых или есть заполненные Items, или нет никаких, и их нужно грузить отдельно.

S>Некоторые из них можно получить, подергав за неочевидные настройки какого-то контекста. Изучение этих неочевидных настроек и составляет квалификацию опытного разработчика под Full-blown ORM. При этом некоторые из возможностей вообще остаются неизвестными даже для самых продвинутых разработчиков — к примеру, асинхронная модель исполнения.


Преимущество ОРМ здесь в том, что он позволяет управлять способом, которым грузится коллекция Айтемов, что позволяет настраивать и оптимизировать уже после разработки, в процессе нагрузочного тестирования. Если окажется, что злая отложенная загрузка хоть и тормозит по определению, но не в критических местах, и работе не особо мешает, то оставляем все как есть, если же сильно уменьшает производительность — то можно начать заниматся настройкой — начиная от выключения отложенной загрузки для конкретного свойства, заканчивая загрузкой Order and all Items одним оптимизированным запросом.

S>Поэтому, продолжая твою терминологию, если клиентскому коду "насрать", то гарантированно получится "говно".

Ну тут не поспоришь
There is no such thing as the perfect design.
Re[4]: роль ООП при работе с данными
От: Sinclair Россия https://github.com/evilguest/
Дата: 25.11.08 09:53
Оценка: +2
Здравствуйте, Sergey T., Вы писали:

ST>Если дела обстоят именно так, как Вы описываете, тогда действительно, делать Order.Items свойством — это ошибка проектирования.


S>>Все эти полезные подробности, вытекающие из удаленного характера Items, скрыты за тупым геттером.

ST>См. выше. Однако, рассмотрите также и ситуацию, когда Ордер.Айтемс — это именно свойство Ордер. С семантикой свойства. Ни один Айтем без заказа не существует. Удаляются они все вместе. Ну и так далее. Скажите, в таком случае отложенная загрузка — тоже плохо?
Естественно. Совершенно неважно, что айтемы не могут жить без ордера.
Во-первых, это неправда — в топике Иван приводил, почему. В частности, менеджера поставок вообще не интересует, в каких заказах расположены айтемы.
С его точки зрения, айтемы принадлежат товару.

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

ST>Кстати, почему это Вы говорите, что Items имеют "удаленный" характер?

Потому что расстояние от сервера приложений до СУБД на несколько порядков больше, чем до собственной памяти.

ST>Преимущество ОРМ здесь в том, что он позволяет управлять способом, которым грузится коллекция Айтемов, что позволяет настраивать и оптимизировать уже после разработки, в процессе нагрузочного тестирования. Если окажется, что злая отложенная загрузка хоть и тормозит по определению, но не в критических местах, и работе не особо мешает, то оставляем все как есть, если же сильно уменьшает производительность — то можно начать заниматся настройкой — начиная от выключения отложенной загрузки для конкретного свойства, заканчивая загрузкой Order and all Items одним оптимизированным запросом.

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

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


S>>Поэтому, продолжая твою терминологию, если клиентскому коду "насрать", то гарантированно получится "говно".

ST>Ну тут не поспоришь
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 10:27
Оценка:
Здравствуйте, Sergey T., Вы писали:

ST>Иногда создается такое впечатление, что единственное отличие "толстой" модели от "тонкой" — это ленивая загрузка.

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

ST>Причем обсуждаемая в контексте клиента. Хотя в большинстве случаев клиент удаленный, и "ленивую" загрузку явно практически не использует, а использует ДТО.

Вот, DTO — это второй костыль.

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

Объективное удобство стройной модели в том, что она менее связна.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[3]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 10:32
Оценка: 13 (2) +2 -1
Здравствуйте, Sergey T., Вы писали:

>> ...

ST>Иногда создается такое впечатление, что единственное отличие "толстой" модели от "тонкой" — это ленивая загрузка.

Создается. Но ведь с другой стороны — толстая модель ведь не обязывает нас использовать ленивую загрузку — независимо от того, как там оформлены связи между сущностями. Никто не мешает делать загрузку явно, и это будет по-прежнему "жирно".
Не говоря уж о том, что в некоторых случаях представление связанных сущностей через какое-нибудь св-во типа Items — например, у нас отношение многое-ко-многим — просто-напросто неразумно, независимо от модели.

ST>Причем обсуждаемая в контексте клиента. Хотя в большинстве случаев клиент удаленный, и "ленивую" загрузку явно практически не использует, а использует ДТО. Хотя возможно есть решения, когда объекты передачи данных тоже используют отложенную загрузку, однако они из области частных решений.


ST>Как мне кажется, единственное объективное удобство тонкой модели в том, что она естественным образом ложится на сервис-ориентированную архитектуру, более того, она специально разрабатывается для такой архитектуры. Это позволяет при желании сэкономить на написании выделенного (отдельного) фасада системы.


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

Меня возмущает критика толстой модели, приведенная в статье по ссылке. Критика — абсолютно несостоятельна. Какие бы там ни были наши предпочтения и как бы ни хотелось "защитить" EF, но выдавать утверждения в стиле, что толстая модель "все валит в кучу", предполагает смешивать разнородный код да еще так, что какая-то нибудь сериализация в ХМЛ будет тесно переплена с дата-аксесом, а уж алгоритмы поменять независимо от данных, как тут Синлер распыляется, это вообще анрыл — это по-моему просто неправильно. Да еще, извините, Фаулера тут поминать как "мальчика для битья".
Критика должна быть разумной. И критика конкретно NHibernate != киритка толстой модели вообще.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[4]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 11:30
Оценка: 1 (1)
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Но ведь с другой стороны — толстая модель ведь не обязывает нас использовать ленивую загрузку — независимо от того, как там оформлены связи между сущностями. Никто не мешает делать загрузку явно, и это будет по-прежнему "жирно".

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

ВВ>Меня возмущает критика толстой модели, приведенная в статье по ссылке.

Есть курсы по управлению гневом.. )

ВВ> Критика — абсолютно несостоятельна.

Просто надо внимательно читать.

ВВ>но выдавать утверждения в стиле, что толстая модель "все валит в кучу",

Цитату можно?

ВВ> предполагает смешивать разнородный код да еще так, что какая-то нибудь сериализация в ХМЛ будет тесно переплена с дата-аксесом, а уж алгоритмы поменять независимо от данных, как тут Синлер распыляется, это вообще анрыл — это по-моему просто неправильно.

...
ВВ>Какие бы там ни были наши предпочтения и как бы ни хотелось "защитить" EF,
ВВ> И критика конкретно NHibernate != киритка толстой модели вообще.

- Иногда письма не доходят.
— Да, бывалыча пишешь письмо, получаешь ответ и понимаешь — не дошло письмо, не дошло.


ВВ>Критика должна быть разумной.

О! Истину глаголешь.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[5]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 11:50
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>Но ведь с другой стороны — толстая модель ведь не обязывает нас использовать ленивую загрузку — независимо от того, как там оформлены связи между сущностями. Никто не мешает делать загрузку явно, и это будет по-прежнему "жирно".

IB>Есть проблема. Если не использовать ленивую загрузку в жирной модели, то при обращении к одному объекту, в память поднимется вся база.

Кроме "грузить неявно через ленивую загрузку" и "грузить сразу все" других вариантов не видишь?

ВВ>>Меня возмущает критика толстой модели, приведенная в статье по ссылке.

IB>Есть курсы по управлению гневом.. )

А я спокоен. Очень спокоен. Очень-очень спокоен. Ты что, утверждаешь, что я не спокоен?!

ВВ>> Критика — абсолютно несостоятельна.

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

Я прочитал внимательно. А вот остальные участники дискуссии, как мне кажется, нет.

ВВ>>но выдавать утверждения в стиле, что толстая модель "все валит в кучу",

IB>Цитату можно?

Например:

Именно по этому, привязывать определенным данным какое-либо поведение посредством "жирной" модели — дурная затея. Во-первых, меняя в десятый раз поведение данные нужно оставлять неизменными. Во-вторых, добавляя новое поведение, надо его просто добавлять, а не менять старое и не накручивать поверх старого, при этом стараясь оставить данные по прежнему неизменными.
...
Если, следуя логике "жирной" модели, класс с персистентными данными оборудован методом .Save(), сохраняющим данные в БД — то, когда понадобится хранить те же данные в кеше, вьюстейте, сессии или сериализовать еще куда-нибудь, придется либо добавить еще один метод .Save(), то есть, модифицировать существующий класс, вместо того, чтобы просто добавить новый, либо размещать новый Save() в другом классе, не понятно по какой причине ставя Save() в базу данных в привилегированное положение по отношению к другим Save-ам.
...
На первый взгляд, кажется что в "жирнной" модели код хорошо инкапсулирован, но это не так. На самом деле, как это ни странно, лучше всего код инкапсулруется именно "стройной" модели. Инкапсуляция призвана скрывать детали реализации за публичным контрактом. Однако, в случае "жирной" модели детали реализации, допустим, сериализации в XML никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД, в рамках одного "жирного" класса. Этот никак, по смыслу, не связанный между собой функционал, вполне может начать влиять друг на друга при неаккуратной реализации, а компилятор никак не сможет это дело проконтролировать.


И там еще много такого. Почитайте.

ВВ>> предполагает смешивать разнородный код да еще так, что какая-то нибудь сериализация в ХМЛ будет тесно переплена с дата-аксесом, а уж алгоритмы поменять независимо от данных, как тут Синлер распыляется, это вообще анрыл — это по-моему просто неправильно.

IB>...
ВВ>>Какие бы там ни были наши предпочтения и как бы ни хотелось "защитить" EF,
ВВ>> И критика конкретно NHibernate != киритка толстой модели вообще.
IB>

IB>- Иногда письма не доходят.
IB>- Да, бывалыча пишешь письмо, получаешь ответ и понимаешь — не дошло письмо, не дошло.


Если нечего сказать, то лучше и не говорить.

ЗЫ. Я спокоен
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[6]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 12:24
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Кроме "грузить неявно через ленивую загрузку" и "грузить сразу все" других вариантов не видишь?

Давай другие.

ВВ>Я прочитал внимательно. А вот остальные участники дискуссии, как мне кажется, нет.

Ага, один ты в белом...

ВВ>>>но выдавать утверждения в стиле, что толстая модель "все валит в кучу",

IB>>Цитату можно?

ВВ>Например:

Во первых, и где тут про то, что "толстая модель все валит в кучу"? То есть по сути так оно и есть, но конкретно этой фразы я нигде не говорил.
А во-вторых, что именно из процитированного не устраивает?

ВВ>И там еще много такого. Почитайте.

Я прекрасно помню, что писал.

ВВ>Если нечего сказать, то лучше и не говорить.

О! Заметь, это не я предложил.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[7]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 12:43
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>Кроме "грузить неявно через ленивую загрузку" и "грузить сразу все" других вариантов не видишь?

IB>Давай другие.

1) Грузить явно по требованию
2) Проектировать граф иначе (вкорячивать св-во ChildItems — это далеко не всегда в стиле ООП)

ВВ>>Я прочитал внимательно. А вот остальные участники дискуссии, как мне кажется, нет.

IB>Ага, один ты в белом...

На пару с Фаулером.

ВВ>>>>но выдавать утверждения в стиле, что толстая модель "все валит в кучу",

IB>>>Цитату можно?

ВВ>>Например:

IB>Во первых, и где тут про то, что "толстая модель все валит в кучу"? То есть по сути так оно и есть, но конкретно этой фразы я нигде не говорил.

Цитирую по второму кругу:
1) "добавляя новое поведение, надо его просто добавлять, а не менять старое и не накручивать поверх старого"

2) "когда понадобится хранить те же данные в кеше, вьюстейте, сессии или сериализовать еще куда-нибудь, придется либо добавить еще один метод .Save(), то есть, модифицировать существующий класс"

3) "в случае "жирной" модели детали реализации, допустим, сериализации в XML никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД, в рамках одного "жирного" класса. Этот никак, по смыслу, не связанный между собой функционал, вполне может начать влиять друг на друга при неаккуратной реализации"

Менять старое поведение ради добавления нового, писать новый Сейв внутри объекта для поддержки сериализации, детали реализации дата-аксеса "никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД" — это все, конечно же, совершенно не говорит о том, что у нас все свалено в одну кучу.

IB>А во-вторых, что именно из процитированного не устраивает?


Все.

ВВ>>И там еще много такого. Почитайте.

IB>Я прекрасно помню, что писал.

Ага, вот где собака-то порылась

ВВ>>Если нечего сказать, то лучше и не говорить.

IB>О! Заметь, это не я предложил.

Тяжело воспринимаем критику, товарищ.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[8]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 13:11
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>1) Грузить явно по требованию

И иметь объекты с наполовину не заполненными данными?

ВВ>2) Проектировать граф иначе (вкорячивать св-во ChildItems — это далеко не всегда в стиле ООП)

Об этом и речь.

ВВ>На пару с Фаулером.

Это вряд ли.

ВВ>Цитирую по второму кругу:

Отвечаю по второму кругу. Где конкретно в этих цитатах фраза "жирная модкль все валит в кучу"? Что конкретно неустраивает в процитированном?

ВВ>Все.

Твои проблемы.

ВВ>Тяжело воспринимаем критику, товарищ.

Критику я воспринимаю нормально, а вот агрессивный поток сознания без внятной мысли — не воспринимаю вообще.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[9]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 13:29
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>1) Грузить явно по требованию

IB>И иметь объекты с наполовину не заполненными данными?

Проектируем граф иначе, и таких проблем не будет.

ВВ>>2) Проектировать граф иначе (вкорячивать св-во ChildItems — это далеко не всегда в стиле ООП)

IB>Об этом и речь.

Нет, речь о том, что жирная модель каким-то боком приравнивается к необходимости всегда иметь ленивый ChildItems.
Жирная модель — это ОО-модель. Она ни к чему кроме ОО не приравнивается.

ВВ>>Цитирую по второму кругу:

IB>Отвечаю по второму кругу. Где конкретно в этих цитатах фраза "жирная модкль все валит в кучу"? Что конкретно неустраивает в процитированном?

Если нравится играть в дурачка и делать вид, что не понимаешь, что сам же писал:

детали реализации, допустим, сериализации в XML никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД, в рамках одного "жирного" класса

и что

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

то ради бога.
Ждем новых статей. Пишите еще.

ВВ>>Все.

IB>Твои проблемы.

Нет, ты не прав. Это не мои проблемы. Это проблемы написавшего, раз у него такое превратное понимание технологии. И неумение спорить, к сожалению.

ВВ>>Тяжело воспринимаем критику, товарищ.

IB>Критику я воспринимаю нормально, а вот агрессивный поток сознания без внятной мысли — не воспринимаю вообще.

Письма, видимо, действительно не доходят.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[10]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 14:55
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Проектируем граф иначе, и таких проблем не будет.

Об этом и речь. Надо проектировать как в стройной модели.

ВВ>Нет, речь о том, что жирная модель каким-то боком приравнивается к необходимости всегда иметь ленивый ChildItems.

Смотришь в книгу — видишь фигу. В жирной модели есть ChildItems, а уж ленивый ли он — сами разбирайтесь.

ВВ>Жирная модель — это ОО-модель.

Что такое ОО-модель?

ВВ>детали реализации, допустим, сериализации в XML никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД, в рамках одного "жирного" класса

ВВ>и что
ВВ>не связанный между собой функционал, вполне может начать влиять друг на друга
И с чем из этого ты не согласен?

ВВ>Ждем новых статей. Пишите еще.

Обязательно..

ВВ> Это проблемы написавшего, раз у него такое превратное понимание технологии.

У писавшего очень правильное понимание технологии. Проблемы у тех, кто влезает не разобравшись в том, что написано.

ВВ>И неумение спорить, к сожалению.

Было бы с чем.

ВВ>Письма, видимо, действительно не доходят.

Писать пробовали?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[11]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 15:15
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>Проектируем граф иначе, и таких проблем не будет.

IB>Об этом и речь. Надо проектировать как в стройной модели.

Правильный дизайн — не прерогатива стройной модели.

ВВ>>Нет, речь о том, что жирная модель каким-то боком приравнивается к необходимости всегда иметь ленивый ChildItems.

IB>Смотришь в книгу — видишь фигу.

Потому что кроме "фиги" в книге ничего нет.

IB>В жирной модели есть ChildItems, а уж ленивый ли он — сами разбирайтесь.


В жирной модели нет ChildItems. Она есть в воспаленном мозгу разработчика. Жирная модель — это объектно-ориентированная модель, не больше и не меньше. И композиция не единственный способ построения модели.

ВВ>>детали реализации, допустим, сериализации в XML никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД, в рамках одного "жирного" класса

ВВ>>и что
ВВ>>не связанный между собой функционал, вполне может начать влиять друг на друга
IB>И с чем из этого ты не согласен?

Со смыслом.

[передергивания поскипаны]
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re: роль ООП при работе с данными
От: Blazkowicz Россия  
Дата: 25.11.08 16:07
Оценка: 2 (1) +2
Здравствуйте, IB, Вы писали:

IB>http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686


Итак, имеем компиляцию из
http://www.rsdn.ru/forum/message/2795918.aspx
Автор:
Дата: 14.01.08

http://www.rsdn.ru/forum/message/2776548.aspx
Автор: mazurkin
Дата: 23.12.07

http://www.rsdn.ru/forum/message/2705199.aspx
Автор: Blazkowicz
Дата: 24.10.07

и возможно нескольких других тем.

Один только момент я не допонял. Как по мне тема Rich vs Anemic Domain Model к материалу зря привязана. Отсюда и критика про смешинвание разных тем в кучу.

Rich vs Anemic Domain Model подразумевает именно наличие/отсутствие большого количества логики в классах с данными. То есть Rich DM подразумевает отсутствии Service как слоя инкапсулирующего бизнес логику.

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

По-моему темы перпендикулярны, так как я легко себе могу представить все четыре комбинации этих пар.
Слабо связанные данные с логикой
Слабо связанные без логики
Сильно связанные данные с логикой
Сильно связанные без логики
Re[12]: роль ООП при работе с данными
От: Кэр  
Дата: 25.11.08 16:07
Оценка: +1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>>>детали реализации, допустим, сериализации в XML никак не скрыты от деталей реализации какого-нибудь рассчета или сохранения в БД, в рамках одного "жирного" класса

ВВ>>>и что
ВВ>>>не связанный между собой функционал, вполне может начать влиять друг на друга
IB>>И с чем из этого ты не согласен?

ВВ>Со смыслом.


Я так понимаю — IB пытается (ну ладно не особо пытается ) получить от вас какие-то детали возражений. Он очевидно не хочет рассыпаться в объяснениях, почему он считает выделенное правильным. Но если вы пытаетесь от него чего-то добиться — почему бы вам не привести больше деталей в своих рассуждениях, почему вы не согласны с выделенным.
Re[4]: роль ООП при работе с данными
От: Blazkowicz Россия  
Дата: 25.11.08 16:09
Оценка:
Здравствуйте, IB, Вы писали:

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

Ну, почему сразу толпа. Я и набегаю. Тема интересная, есть над чем задуматся. Но при этом никто не запрещает разрывать модель и отказатся от ленивой загрузки используя все тот же ORM. И даже комбинировать оба варианта сильной и слабой связанности данных.
Re: роль ООП при работе с данными
От: Blazkowicz Россия  
Дата: 25.11.08 16:10
Оценка:
И ещё один вопрос к автору. Правильно ли я понимаю что в "стройной" модели таки планируется хранить значения PK в полях и коллекциях?
Re[5]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 16:50
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B> Но при этом никто не запрещает разрывать модель и отказатся от ленивой загрузки используя все тот же ORM.

Да не мешает, конечно.. Но обычно этого не делают, так как во всех примерах работы с ORM приводится именно жирная модель в самом ее плохом проявлении.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[12]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 16:50
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Правильный дизайн — не прерогатива стройной модели.

Да, наверное стоит переформулировать — "один из признаков правильного дизайна — стройная модель", вот так будет правильно.

ВВ>Потому что кроме "фиги" в книге ничего нет.

Пока не разберешься — и не будет..

ВВ>В жирной модели нет ChildItems.

Формально нет, а по факту — есть.

ВВ> Жирная модель — это объектно-ориентированная модель, не больше и не меньше.

Да, это кривая объектно-ориентированная модель.
Я, кстати, так и не услышал от тебя, что же такое — объектно-ориентированная модель.

ВВ>Со смыслом.

Твои проблемы...
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[2]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 16:50
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Rich vs Anemic Domain Model подразумевает именно наличие/отсутствие большого количества логики в классах с данными. То есть Rich DM подразумевает отсутствии Service как слоя инкапсулирующего бизнес логику.

B>Вторая же тема именно в способе организации модели данных, которые либо сильно связаны, держа ссылку друг на друга, либо связаны слабо на уровне базы, без сильных связей в классах модели данных.

Совершенно верно. =) Я уже отвечал на это: Re[10]: роль ООП при работе с данными
Автор: IB
Дата: 27.10.08
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[2]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 16:50
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Правильно ли я понимаю что в "стройной" модели таки планируется хранить значения PK в полях и коллекциях?

В целом да, за исключением вырожденых случаев.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[13]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 16:56
Оценка:
Здравствуйте, Кэр, Вы писали:

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


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

Order<Database> order = new Oder<Database>();

или даже

Order<Database,NewYearDiscount> order = new Order<Database,NewYearDiscount>();

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

А откуда берется правило, что в жирной модели если есть метод Save(), то туда надо непременно напихать все "что у нас есть" — и код доступа к данным и какую-нибудь сериализацию и бизнес-логику? Что, Фаулер об этом писал?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[13]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 17:24
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>Правильный дизайн — не прерогатива стройной модели.

IB>Да, наверное стоит переформулировать — "один из признаков правильного дизайна — стройная модель", вот так будет правильно.

Ну-ну. ООП в топку?

ВВ>>В жирной модели нет ChildItems.

IB>Формально нет, а по факту — есть.

Хреновые у вас факты.

ВВ>> Жирная модель — это объектно-ориентированная модель, не больше и не меньше.

IB>Да, это кривая объектно-ориентированная модель.

Не делайте ее кривой.

IB>Я, кстати, так и не услышал от тебя, что же такое — объектно-ориентированная модель.


Строящаяся на полиморфизме классов, имеющих родовые отношения, обладающих состоянием и поведением.
А вообще почитайте Фаулера, всуе упомянутого. У него много чего интересного есть кроме "практика показывает".

ВВ>>Со смыслом.

IB>Твои проблемы...
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[14]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 20:40
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Ну-ну. ООП в топку?

Счегобыс ?

ВВ>Не делайте ее кривой.

То есть, используйте стройную модель — собственно о чем я и пишу.

ВВ>Строящаяся на полиморфизме классов, имеющих родовые отношения, обладающих состоянием и поведением.

Все веселее.
Что такое "полиморфизм классов" и "родовые отношения"?
Мешать состояние и поведение — это обязательное требование?

ВВ>А вообще почитайте Фаулера, всуе упомянутого.

У него, конечно, много чего упомянуто, но подобного там точно нет.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[14]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 20:40
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Я в этой теме уже неоднократно говорил, что никто не мешает нам вынести дата-логику и бизнес-логику,

Что такое "дата-логика"?

ВВ> а внутри класса осуществлять просто делегацию.

Можно, только вопрос — зачем? Какие преимущества это даст и от каких проблем избавит?

ВВ>это лишь один из многочисленных вариантов.

Другие такие же забавные?

ВВ>И все это — по крайней мере с т.з. зрения — будет выглядеть как жирная модель.

Формально уже нет, а по факту это будет не пойми что.

ВВ>А откуда берется правило, что в жирной модели если есть метод Save(), то туда надо непременно напихать все "что у нас есть" — и код доступа к данным и какую-нибудь сериализацию

Простой вопрос: Вот есть у нас в жирной модели у класса метод Save() который сериализует состояние класса в БД. Куда ты поместишь Save(), который должен сериализовать то же состояние в XML?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[15]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 20:57
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>И все это — по крайней мере с т.з. зрения — будет выглядеть как жирная модель.

IB>Формально уже нет, а по факту это будет не пойми что.

Формально — это как? Клиент ничего не должен знать о том, как именно реализован этот самый Save()

ВВ>>А откуда берется правило, что в жирной модели если есть метод Save(), то туда надо непременно напихать все "что у нас есть" — и код доступа к данным и какую-нибудь сериализацию

IB>Простой вопрос: Вот есть у нас в жирной модели у класса метод Save() который сериализует состояние класса в БД. Куда ты поместишь Save(), который должен сериализовать то же состояние в XML?

class Order<T> where T : IPersistanceModel

class DatabasePersistanceModel : IPersistanceModel

class XmlPersistanceModel : IPersistanceModel

Не нравится генерики — можно и без них. А мне вот нравится, что я определяю тип персистенции класса уже по имени типа и например сущность, полученную из ХМЛ-я, в принципе не смогу засунуть в базу.
И это преимущества ОО подхода, где сама сущность наделена поведением специфичным конкретно для нее, а не какой ДатабейзСервис, которому на все...
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[15]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 21:04
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>А вообще почитайте Фаулера, всуе упомянутого.

IB>У него, конечно, много чего упомянуто, но подобного там точно нет.

Низачет.

http://martinfowler.com/bliki/AnemicDomainModel.html

По поводу "хилой" модели:

The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters

... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[16]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 23:22
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Низачет.

ВВ>http://martinfowler.com/bliki/AnemicDomainModel.html
Вот я и говорю — Фаулеру — низачет. =)

ВВ>По поводу "хилой" модели:

Так где там "полиморфизм классов" и "родовые отношения"?
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[16]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 25.11.08 23:22
Оценка: +1 -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Формально — это как?

Формально — это по определению жирной модели.

ВВ>class Order<T> where T : IPersistanceModel

Нет, я спрашивал не об этом. Ты можешь читать что тебе пишут? Могу еще раз, мне не сложно: в жирной модели у класса метод Save() который сериализует состояние класса в БД. Куда ты поместишь Save(), который должен сериализовать то же состояние в XML?
И ты так и не ответил на вопрос, а ради чего собственно весь этот зоопарк?

ВВ> А мне вот нравится, что я определяю тип персистенции класса уже по имени типа и например сущность, полученную из ХМЛ-я, в принципе не смогу засунуть в базу.

Дааа... "Как убить себя гранатой" (с) Понимаешь, в реальной жизни нужно ровно наоборот, не иметь десяток моделей, отдельно на каждое хранилище, а одно и то же состояние уметь хранить в разных местах и вообще переиспользовать во всех возможных сценариях.

ВВ>И это преимущества ОО подхода, где сама сущность наделена поведением специфичным конкретно для нее, а не какой ДатабейзСервис, которому на все...

Преимущество перед чем? И я продолжаю неулавливать, что ты понимаешь под ОО подходом...
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[17]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 23:53
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>class Order<T> where T : IPersistanceModel

IB>Нет, я спрашивал не об этом. Ты можешь читать что тебе пишут? Могу еще раз, мне не сложно: в жирной модели у класса метод Save() который сериализует состояние класса в БД. Куда ты поместишь Save(), который должен сериализовать то же состояние в XML?
IB>И ты так и не ответил на вопрос, а ради чего собственно весь этот зоопарк?

Ты будешь мозг включать, читая ответы? Или для критики Фаулера мозг не требуется?
Метод Save помещу в отдельную реализацию PersistanceModel. Если потребуется совмесщение сериализации в ХМЛ и базы — то будет гибридная PersistanceModel.

ВВ>> А мне вот нравится, что я определяю тип персистенции класса уже по имени типа и например сущность, полученную из ХМЛ-я, в принципе не смогу засунуть в базу.

IB>Дааа... "Как убить себя гранатой" (с) Понимаешь, в реальной жизни нужно ровно наоборот, не иметь десяток моделей, отдельно на каждое хранилище, а одно и то же состояние уметь хранить в разных местах и вообще переиспользовать во всех возможных сценариях.

Делай гибридные модели. А что там дает модель сервисов в этом плане? Да то же самое.

ВВ>>И это преимущества ОО подхода, где сама сущность наделена поведением специфичным конкретно для нее, а не какой ДатабейзСервис, которому на все...

IB>Преимущество перед чем? И я продолжаю неулавливать, что ты понимаешь под ОО подходом...

Преимущество перед хилой моделью. А под ООП я понимаю ровно то же что и Фаулер, которого не мешает все-таки почитать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[17]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 25.11.08 23:53
Оценка: +1 -1
Здравствуйте, IB, Вы писали:

ВВ>>Низачет.

ВВ>>http://martinfowler.com/bliki/AnemicDomainModel.html
IB>Вот я и говорю — Фаулеру — низачет. =)

Ну да, скомпилировали парочку флеймов с РСДНа, сделали статью — и все Фаулеру низачет, мы теперь сами себе авторитеты. Может, сначала стоить его почитать? Например, Patterns of enterprise application architecture. А после этого свою статью.
И заодно подумать над тем, что у Domain Model вообще есть проблемы, которые абсолютно не снимаются, когда мы делаем ее анемичной.
А заниматься придумыванием хитрых сценариев, которые якобы легко и просто решаются в анемичной модели, а в жирной якобы приводят к большим проблемам — дело неблагодарное.
Ты, наверное, думаешь, что Фаулер не допер, что плохо бизнес-логику и код доступа к данным в одном классе смешивать? Ну-ну

ВВ>>По поводу "хилой" модели:

IB>Так где там "полиморфизм классов" и "родовые отношения"?

Там объясняется, почему анемичная модель не является объектно-ориентированной.

А по поводу — "полиморфизм классов" и "родовые отношения". Что конкретно непонятно? Что такое полиморфизм и наследование? Ну тогда, пожалуй, и правда рановато Фаулера читать.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[18]: роль ООП при работе с данными
От: Blazkowicz Россия  
Дата: 26.11.08 07:36
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Ну да, скомпилировали парочку флеймов с РСДНа, сделали статью — и все Фаулеру низачет, мы теперь сами себе авторитеты. Может, сначала стоить его почитать? Например, Patterns of enterprise application architecture. А после этого свою статью.

Читали.
ВВ>И заодно подумать над тем, что у Domain Model вообще есть проблемы, которые абсолютно не снимаются, когда мы делаем ее анемичной.
И что? Мы ведь не говорим о панацее. Некоторые проблемы решаются, некоторые — нет.

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

ВВ>Ты, наверное, думаешь, что Фаулер не допер, что плохо бизнес-логику и код доступа к данным в одном классе смешивать? Ну-ну
Причем здесь код доступа данных? Если есть что сказать в защиту не Anemic Domain Model, то хотелось бы увидеть комментарии в этом топике
http://rsdn.ru//forum/message/2705199.aspx
Автор: Blazkowicz
Дата: 24.10.07

Там конкретный вопрос именно про фаулеровский подход избавления от Anemic Domain Model, без мешанины со связанностью самих данных.

ВВ>Там объясняется, почему анемичная модель не является объектно-ориентированной.

Верно и других аргументов не приводится. Но ООП, ведь, тоже не панацея. Поэтому на аргумент тянет слабо.

ВВ>А по поводу — "полиморфизм классов" и "родовые отношения". Что конкретно непонятно? Что такое полиморфизм и наследование? Ну тогда, пожалуй, и правда рановато Фаулера читать.

Ну, вот. Опять до флейма скатываемся.
Re[6]: роль ООП при работе с данными
От: KRA Украина  
Дата: 26.11.08 08:03
Оценка:
Здравствуйте, IB, Вы писали:

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


B>> Но при этом никто не запрещает разрывать модель и отказатся от ленивой загрузки используя все тот же ORM.

IB>Да не мешает, конечно.. Но обычно этого не делают, так как во всех примерах работы с ORM приводится именно жирная модель в самом ее плохом проявлении.
Насчёт всех примеров это Вы переборщили. В стандартном примере petclinic поставки spring, где демонстрируется в том числе и работа с ORM — тонкая модель.
Re[18]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 26.11.08 09:47
Оценка:
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Ну да, скомпилировали парочку флеймов с РСДНа, сделали статью — и все Фаулеру низачет, мы теперь сами себе авторитеты.

Подвох в том, что я скомпилировал исключительно из своихсообщений в этих флеймах, так что мимо.

ВВ> Может, сначала стоить его почитать?



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

Конечно неблагодарное, вот и не занимайся.

ВВ>Ты, наверное, думаешь, что Фаулер не допер, что плохо бизнес-логику и код доступа к данным в одном классе смешивать? Ну-ну

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

ВВ>Там объясняется, почему анемичная модель не является объектно-ориентированной.

Неубедительно это как-то объясняется, и я бы даже сказал не объясняется, а постулируется. А вот, к примеру, Меерс как раз наоборот, довольно убедительно показывает, что стройные классы вполне-себе объектно ориентированы.

ВВ>А по поводу — "полиморфизм классов" и "родовые отношения". Что конкретно непонятно?

Конкретно непонятно, что эти термины означают и что ты вообще имеешь ввиду, когда говоришь "объектно-ориентировано".
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[18]: роль ООП при работе с данными
От: IB Австрия http://rsdn.ru
Дата: 26.11.08 09:47
Оценка: -1
Здравствуйте, Воронков Василий, Вы писали:

ВВ>Ты будешь мозг включать, читая ответы? Или для критики Фаулера мозг не требуется?

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

ВВ>Метод Save помещу в отдельную реализацию PersistanceModel.

Какой из методов? Я тебе задал вполне конкретный вопрос, на него сложно ответить?
Давай код, для простоты — вот у нас жирная модель:
public class Order
{
    public int OrderId {get;set;}
    ....
    public void Save()
    {
        // Сохранение в БД
    }
}

Теперь надо добавить сохранение в XML, куда добавляем — твоя версия?

ВВ> Если потребуется совмесщение сериализации в ХМЛ и базы — то будет гибридная PersistanceModel.

Что такое "гибридная PersistanceModel"?

ВВ>Делай гибридные модели.

Это что такое?

ВВ>Преимущество перед хилой моделью.

Ага, чем армяне. В чем преимущество-то? Или ты опять просто потрындеть прищшел?

ВВ> А под ООП я понимаю ровно то же что и Фаулер,

Вот в этом я конкретно сомневаюсь.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[19]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 26.11.08 11:03
Оценка:
Здравствуйте, IB, Вы писали:

ВВ>>Метод Save помещу в отдельную реализацию PersistanceModel.

IB>Какой из методов? Я тебе задал вполне конкретный вопрос, на него сложно ответить?
IB>Давай код, для простоты — вот у нас жирная модель:
IB>
IB>public class Order
IB>{
IB>    public int OrderId {get;set;}
IB>    ....
IB>    public void Save()
IB>    {
IB>        // Сохранение в БД
IB>    }
IB>}
IB>

IB>Теперь надо добавить сохранение в XML, куда добавляем — твоя версия?

Видимо, мозг действительно отключен. Сложно представить, что код для сохранения в БД не должен содержаться напрямую в методе Save? У меня есть "модель", в которой описана реализации сохранения в БД для данной сущности. Если мне потребуется создания ХМЛ-сериализации я напишу новую модель. Если потребует сохранять в БД и ХМЛ — модель, использующую две предыдущие модели.
При этом ни разу ничего не поменяю в методе Сейв.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[19]: роль ООП при работе с данными
От: Воронков Василий Россия  
Дата: 26.11.08 11:03
Оценка: 8 (1) +3 -1
Здравствуйте, Blazkowicz, Вы писали:

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

B>И что? Мы ведь не говорим о панацее. Некоторые проблемы решаются, некоторые — нет.

А кто-то утверждает, что это панацея?
Но какой смысл переносить все проблемы именно Domain Model — причем любой Domain Model — конкретно на жирную модель?

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

ВВ>>Ты, наверное, думаешь, что Фаулер не допер, что плохо бизнес-логику и код доступа к данным в одном классе смешивать? Ну-ну
B>Причем здесь код доступа данных? Если есть что сказать в защиту не Anemic Domain Model, то хотелось бы увидеть комментарии в этом топике
B>http://rsdn.ru//forum/message/2705199.aspx
Автор: Blazkowicz
Дата: 24.10.07

B>Там конкретный вопрос именно про фаулеровский подход избавления от Anemic Domain Model, без мешанины со связанностью самих данных.

Аргумент на самом деле простой — анемичная модель не объектно-ориентирована. Так считает Фаулер. Я с ним согласен.
Анемичная модель лишает классы поведения. И это самое поведение, которое должно характеризовывать конкретную сущность выносится в отдельный слой, который представляет собой мешанину из "поведений" различных сущностей.

Почему это плохо?
  • Так как поведение перестает быть частью самого объекта, то этот объект при желании можно наделить поведением, которое изначально не задумывалось для него, которое будет являться неправильным для этого объекта.
  • Класс перестает быть полиморфным. Изменение поведения для этого класса предполагает изменение совершенно внешнего по отношению к нему сервиса. Наследование перестает быть средством изменения поведения. Код, работающий с нашим классом, также перестает быть обощенным. Для изменения поведения мне надо или править существующий сервис (в котором содержится код для других классов, а соответственно потенциально влиять и на него) или же создавать новый сервис. Для того, чтобы решить эту проблему мне придется поднимать совершенно отдельную модель сервисов — с наследованиями, разными реализациями и пр. — которая в итоге придет ровно к тем же проблемам, которые тут так остроумно находят у жирной модели.
  • "Контракт" для класса теряет свой смысл. В нем описываются только данные — не поведение. Контракт для работы с классом подменяется неким общим контрактом сервиса. Изменение, расширение поведения для одно класса приводит к изменению контракта для всего сервиса. Таким образом, изменение одной сущности косвенным образом затрагивает все сущности.
  • Контракт сервиса всегда изыбыточен. Он представляет собой километровую простыню методов, в которой ООП не больше, чем в коде на plain C образца 76 года. Мало того, что он будет постоянно изменяться, так и работать с ним просто-напросто неудобно. Разнородные методы, которые вообще никак не связаны друг с другом, доступ к которым должен, возможно, даже разграничиваться, будут тут соседствовать. Альтернатива — дробление одного сервиса на многие сервисы. Причем чем "легче" будет сервис, тем лучше это все будет выглядеть. В идеале мы придем к тому, что на каждый класс у нас будет по сервису. Занавес.

    Это так, если касаться вопроса вкратце.

    Значит ли это, что анемичная модель плохо, а жирная — хорошо?
    Нет, не значит. Да, жирная модель — это просто-напросто ОО-модель, анемичная — не ОО-модель, а ООП далеко не лучший инструмент не только в отношении работы с данными.

    Но он не настолько плох, как ту пытаются представить.

    ВВ>>Там объясняется, почему анемичная модель не является объектно-ориентированной.

    B>Верно и других аргументов не приводится. Но ООП, ведь, тоже не панацея. Поэтому на аргумент тянет слабо.

    Это тянет на аргумент. Вспомни, чем ОО лучше структурного подхода. И здесь будет все тоже самое. Избавляясь от ООП, мы лишаемся всех его преимуществ.

    И вот, кстати, IB пытается убедить, что анемичная модель самая что ни на есть ООП. На это я и отвечал.
    Да, в ОО-модели класс должен быть наделен поведением, а не представлять собой пустой набор геттеров и сеттеров. Это не значит, что ООП это хорошо или плохо. У ООП немало проблем и безотносительно к текущей теме. Но у ООП другие проблемы.
    Какой смысл описывать откровенное убогое построение жирной модели — фактически доведенное до абсурда — и показывать, что это видите ли именно то, что жирная модель предполагает?

    ВВ>>А по поводу — "полиморфизм классов" и "родовые отношения". Что конкретно непонятно? Что такое полиморфизм и наследование? Ну тогда, пожалуй, и правда рановато Фаулера читать.

    B>Ну, вот. Опять до флейма скатываемся.

    До флейма уже скатились. Изначально я всего-то высказал свое мнение, что критика жирной модели приведенная в блоге несколько "смешивает напитки".
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
  • Re[7]: роль ООП при работе с данными
    От: Blazkowicz Россия  
    Дата: 26.11.08 11:17
    Оценка:
    Здравствуйте, KRA, Вы писали:

    KRA>Насчёт всех примеров это Вы переборщили. В стандартном примере petclinic поставки spring, где демонстрируется в том числе и работа с ORM — тонкая модель.

    Скачал. Посмотрел.
    http://rsdn.ru/forum/message/3187831.1.aspx
    Автор: Blazkowicz
    Дата: 25.11.08

    petclinic как раз пример Anemic Domain Model с точки зрения Фаулера, но "жирная" с точки зрения IB. Под тонкой моделью подразумевается отстствие таких связей как, например, Pet->Visits. Почему? Попробуем PetClinic натянуть на пример из жизни.
    Появились новые требования в ТЗ — интеграция с глобальной системой учета животных в городе. Так вот интеграционному модулю ничего ни про какие визиты знать не надо. Поэтому сущность Pet там излишне "жирная".

    И теперь, допутим у нас нет нашего крутого Hibernate ORM. Не будем уточнять почему. А возьмем и заглянем в
    AbstractJdbcClinic.java:

        public Pet loadPet(int id) throws DataAccessException {
            JdbcPet pet = (JdbcPet) this.petQuery.findObject(id);
            if (pet == null) {
                throw new ObjectRetrievalFailureException(Pet.class, new Integer(id));
            }
            Owner owner = loadOwner(pet.getOwnerId());
            owner.addPet(pet);
            loadVisits(pet);
            return pet;
        }


    Загрузка животного всегда приводит к вычитке списка визитов. Соответственно метод уже не реюзабелен, и для интеграции нужен будет новый.
    А вот JdbcPet.java
    public class JdbcPet extends Pet {
        private int typeId;
        private int ownerId;
    
        public void setTypeId(int typeId) {
            this.typeId = typeId;
        }
        public int getTypeId() {
            return this.typeId;
        }
        public void setOwnerId(int ownerId) {
            this.ownerId = ownerId;
        }
        public int getOwnerId() {
            return ownerId;
        }
    }


    Пример "стройной" модели. Но тут сразу встает резонный вопрос, зачем системе 2 класса Pet.

    Не хочу сказать что я во всем согласен со статьей и безупречностью "стройной" модели, но это как минимум интересный повод задуматься и обсудить. Вообще статье очень не хватает своего PetStore чтобы показать достоинства "стройной" модели.
    Re[20]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 11:32
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ> Сложно представить, что код для сохранения в БД не должен содержаться напрямую в методе Save?

    Это условие задачи, обусловленное жирностью модели, которую ты защищаешь.
    Ты с темы-то не соскакивай...

    ВВ>У меня есть "модель", в которой описана реализации сохранения в БД для данной сущности.

    Речь не о твоей модели, о твоей — отдельный разговор.

    ВВ>Если мне потребуется создания ХМЛ-сериализации я напишу новую модель.

    Модель должна быть одна.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[20]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 11:32
    Оценка: +1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Аргумент на самом деле простой — анемичная модель не объектно-ориентирована.

    Это не аргумент, это тезис, который требует доказательств. А их что-то пока не видать.

    ВВ>Анемичная модель лишает классы поведения.

    Не классы, а данные, что правильно.

    ВВ>
  • Так как поведение перестает быть частью самого объекта, то этот объект при желании можно наделить поведением, которое изначально не задумывалось для него, которое будет являться неправильным для этого объекта.
    А если у класса уже есть какое-то поведение, то при желании его нельзя наделить другим неправильным поведением? Смело.

    ВВ>
  • Класс перестает быть полиморфным.
    Не класс а данные.

    ВВ> Изменение поведения для этого класса предполагает изменение совершенно внешнего по отношению к нему сервиса.

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

    ВВ>Наследование перестает быть средством изменения поведения.

    Лучше бы его вообще не было (я про наследование реализации).

    ВВ>Код, работающий с нашим классом, также перестает быть обощенным.

    Вот это ты не угадал. Такой код гораздо более обобщен, чем в жирной модели.

    ВВ> Для изменения поведения мне надо или править существующий сервис (в котором содержится код для других классов, а соответственно потенциально влиять и на него) или же создавать новый сервис.

    Правильны ответ — создавать новый сервис, в полном следовании OCP.

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

    Естественно не приведет, так как здесь нет фатального недостатка жирной модели — разделяемого персистентного состояния.

    ВВ>
  • "Контракт" для класса теряет свой смысл. В нем описываются только данные — не поведение.
    Не для класса, а для данных.

    ВВ>
  • Контракт сервиса всегда изыбыточен.
    Контракт сервиса оптимален.

    ВВ> В идеале мы придем к тому, что на каждый класс у нас будет по сервису.

    Нет, в идеале будет код скомпонованый в полном соответствии с принципом функциональной кохессии. Что есть хорошо и правильно.

    ВВ>Это так, если касаться вопроса вкратце.

    В кратце, ты совершаешь характерную ошибку начинающего ООП-шника, мешая в одну кашу данные и поведение, не отделяя одно от другого.

    ВВ> Да, жирная модель — это просто-напросто ОО-модель, анемичная — не ОО-модель, а ООП далеко не лучший инструмент не только в отношении работы с данными.

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

    ВВ>Да, в ОО-модели класс должен быть наделен поведением, а не представлять собой пустой набор геттеров и сеттеров.

    Это заблуждение..

    ВВ>Какой смысл описывать откровенное убогое построение жирной модели — фактически доведенное до абсурда — и показывать, что это видите ли именно то, что жирная модель предполагает?

    Это самое что ни на есть типичное и классическое представление жирной модели.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
  • Мы уже победили, просто это еще не так заметно...
    Re[21]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 11:47
    Оценка:
    Здравствуйте, IB, Вы писали:

    ВВ>> Сложно представить, что код для сохранения в БД не должен содержаться напрямую в методе Save?

    IB>Это условие задачи, обусловленное жирностью модели, которую ты защищаешь.
    IB>Ты с темы-то не соскакивай...

    Вот тут-то твое заблуждение. Жирность модели вовсе не предполагает таких условий. Ты походи по ссылкам-то, которые Блажкович постил:

    http://rsdn.ru//forum/message/2705199.aspx
    Автор: Blazkowicz
    Дата: 24.10.07
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[21]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 11:47
    Оценка:
    Здравствуйте, IB, Вы писали:

    ВВ>>Аргумент на самом деле простой — анемичная модель не объектно-ориентирована.

    IB>Это не аргумент, это тезис, который требует доказательств. А их что-то пока не видать.

    Читаем Фаулера. Он это объясняет довольно популярно. И кстати я эти объяснения уже приводил.

    ВВ>>Анемичная модель лишает классы поведения.

    IB>Не классы, а данные, что правильно.

    И при этом мы все еще сомневаемся, что это не ОО модель?

    ВВ>>
  • Так как поведение перестает быть частью самого объекта, то этот объект при желании можно наделить поведением, которое изначально не задумывалось для него, которое будет являться неправильным для этого объекта.
    IB>А если у класса уже есть какое-то поведение, то при желании его нельзя наделить другим неправильным поведением? Смело.

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

    ВВ>>
  • Класс перестает быть полиморфным.
    IB>Не класс а данные.

    Класс, а не данные. Order, Customer, etc. — это именно классы, обладающие поведением, а не труха из атрибутов.

    ВВ>> Изменение поведения для этого класса предполагает изменение совершенно внешнего по отношению к нему сервиса.

    IB>Не для классов, а для данных, что правильно.

    Пластинку заело?

    ВВ>>Наследование перестает быть средством изменения поведения.

    IB>Лучше бы его вообще не было (я про наследование реализации).

    А я не про наследование реализации. О чем кстати четко написано. Услышал звон...?

    ВВ>>Код, работающий с нашим классом, также перестает быть обощенным.

    IB>Вот это ты не угадал. Такой код гораздо более обобщен, чем в жирной модели.

    Путаетесь в показаниях. Как он может быть более обобщен, когда "Правильны ответ — создавать новый сервис".
    А, я понял. Наверное, всякие раз когда сервис меняется, мы пишем свой новый "обобщенный код". Ну тогда претензий нет

    На остальное даже отвечать не хочется. Судя по всему, сказать тебе все-таки нечего. Что ж, жаль.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
  • Re: роль ООП при работе с данными
    От: Аноним  
    Дата: 26.11.08 12:01
    Оценка: -1 :)
    Здравствуйте, QrystaL, Вы писали:

    QL>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686


    Да мы вообще положили прибор всей командой на следующие, простите, технологии:

    Linq, EF, SilverLight, WPF, WWF, ADO.NET Services, CardSpaces.

    Всё что для счастья надо это CLR, ADO.NET, WebServices, WinForms, WebForms, руки из плеч...
    и со временем будет Framework для своей предметной области...
    Re[8]: роль ООП при работе с данными
    От: Ziaw Россия  
    Дата: 26.11.08 12:27
    Оценка: 8 (1) +2
    Здравствуйте, Blazkowicz, Вы писали:

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


    +1

    Реально из недостатков rich модели я могу пречислить следующие:

    1. Бизнесметоды меняются и нам приходится иногда держать несколько вариантов одного и того-же бизнесметода в модели. Решается стратегией. В примере Save() добавляем метод Save(IPersister persister). Save() объявляем депрекейтед и сокращаем его использование до минимума.

    2. Объекты имеют избыточное для внешних систем поведение. Решается введением DTO для внешних систем.

    3. Непонятно, какие бизнессклассы должны содержать логику которую нельзя отнести напрямую к конкретному объекту. Решается введением частичным выносом данной логики из модели. От этого модель не перестает быть rich.

    Что мы имеем по этих же случаях в anemic?

    1. Мы имеем то же самое решение, что и в rich, только в другом слое.

    2. Мы можем отдавать объекты модели без DTO, пока нас устраивает набор данных, с другой стороны DTO почти наверняка понадобятся для борьбы с количеством вызвов и объем данных или для security и инкапсуляции.

    3. Тут anemic не конкуренции. Однако это достоинство имеет обратную сторону, в сервисном подходе мы получаем очень жесткие связи между сервисами и рай для процедурного подхода. Либо раздутый набор самих сервисов.

    Отличий при проектировании anemic vs rich не так много, если не забывать о том, что с rich моделью надо сравнивать не anemic, а anemic+BLL.

    Попробовав обе модели я бы сейчас проектировал смешаный вариант, часть логики в сервисах, часть в модели. Трекинг и LL использовать по минимуму, но не шарахаться от них там, где они дают выгоду и не дают серьезных минусов.

    офтопик: это похоже на холивар statefull vs stateless server, мы не имеем чистых реализаций ни того ни другого. Statefull проще превратить в унылое немасштабируемое г с проблемами интеграции.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
    Re[8]: роль ООП при работе с данными
    От: Aikin Беларусь kavaleu.ru
    Дата: 26.11.08 12:37
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Загрузка животного всегда приводит к вычитке списка визитов. Соответственно метод уже не реюзабелен, и для интеграции нужен будет новый.

    B>А вот JdbcPet.java
    JdbcPet может быть приватным и спрятанным внутри DAL. Либо генериться автоматом на основе метаданных (как это делает хибернэйт).
    Пользователи класса Pet ничего не будут о нем знать, используя как обычный Pet.
    Re[20]: роль ООП при работе с данными
    От: Blazkowicz Россия  
    Дата: 26.11.08 12:48
    Оценка: 100 (4) +2
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Аргумент на самом деле простой — анемичная модель не объектно-ориентирована. Так считает Фаулер. Я с ним согласен.

    ВВ>Анемичная модель лишает классы поведения. И это самое поведение, которое должно характеризовывать конкретную сущность выносится в отдельный слой, который представляет собой мешанину из "поведений" различных сущностей.
    Тут и далее мне мерещится одна ошибка в твоих рассуждениям. Мы говорим не про классы вообще, и реализацию систем в целом, а всего лишь про Domain Model и бизнес-логику.

    ВВ>
  • Так как поведение перестает быть частью самого объекта, то этот объект при желании можно наделить поведением, которое изначально не задумывалось для него, которое будет являться неправильным для этого объекта.
    Как минимум два контраргумента можно найти в дургих постах IB.
    — Anemic не отменяет поведения объекта, а лишь ограничивает его, для того чтобы минимизировать зависимости объекта. У Фаулера, например, Domain зависит от Repository. Странно как-то.
    — Нет четкой методологии определения является то или иное поведение частью сущности. Так как существует множество пограничных вариантов.

    ВВ>
  • Класс перестает быть полиморфным. Изменение поведения для этого класса предполагает изменение совершенно внешнего по отношению к нему сервиса. Наследование перестает быть средством изменения поведения. Код, работающий с нашим классом, также перестает быть обощенным. Для изменения поведения мне надо или править существующий сервис (в котором содержится код для других классов, а соответственно потенциально влиять и на него) или же создавать новый сервис. Для того, чтобы решить эту проблему мне придется поднимать совершенно отдельную модель сервисов — с наследованиями, разными реализациями и пр. — которая в итоге придет ровно к тем же проблемам, которые тут так остроумно находят у жирной модели.
    Наследование — зло в первом приближении. Наследование не должно изменять поведение, оно должно его расширять, если таковое имеется.
    Под "отдельной моделью" ты, наверное, имел ввиду "отдельную иерархию".

    Тут что я ещё хочу отметить. Бизнес логика в подавляющем большинстве случаев не является поведением бизнес сущностей. А является процессом, который эти сущности использует. Поэтому всё что ты пишешь правильно, но для случаев, когда сущность, действительно, обладает каким-то поведением. Но во многих примерах поведение приписывается сущности ошибочно. Например, заказ, это всего лишь бумажка с данными. У него нет поведения. И операция "оформить заказ" это поведение оформителя заказов, а не заказа. В свою очередь "оформитель заказов" — сущность, зачастую, напрочь лишенная данных.


    ВВ>
  • "Контракт" для класса теряет свой смысл. В нем описываются только данные — не поведение. Контракт для работы с классом подменяется неким общим контрактом сервиса. Изменение, расширение поведения для одно класса приводит к изменению контракта для всего сервиса. Таким образом, изменение одной сущности косвенным образом затрагивает все сущности.
    Это всё верно, для классов. Но для построения модели предметной области не важно. И вывод у тебя ложный. Если я добавлю поле в класс Order и создам ExtendedOrder а так же обновлю сервис для использования этого нового класса, то это вообще никак не отразится на остальные сущности, используемые сервисом.


    ВВ>Контракт сервиса всегда изыбыточен.

    Спорное утверждение, ниразу не аргументированое нижеидущими выводами.

    ВВ>Он представляет собой километровую простыню методов, в которой ООП не больше, чем в коде на plain C образца 76 года. Мало того, что он будет постоянно изменяться, так и работать с ним просто-напросто неудобно.

    Практика показала что достаточно удобно.

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

    Это зависит от дизайна иерархии сервисов. И то что методы с друг другом не связаны это тоже отчасти верно.

    ВВ>Альтернатива — дробление одного сервиса на многие сервисы. Причем чем "легче" будет сервис, тем лучше это все будет выглядеть. В идеале мы придем к тому, что на каждый класс у нас будет по сервису. Занавес.

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

    ВВ>Но он не настолько плох, как ту пытаются представить.

    Никто не говорит что ООП плох. Просто он не всегда удобен для реализации Domain Model. Особенно в трехзвенке.

    ВВ>Это тянет на аргумент. Вспомни, чем ОО лучше структурного подхода. И здесь будет все тоже самое. Избавляясь от ООП, мы лишаемся всех его преимуществ.

    Подход не предлагает избавится от ООП повсеместно, а лишь в реализации Domain. И опять же не столько от самого ООП, сколько от проблем вызываных различным пониманием ООП.

    ВВ>И вот, кстати, IB пытается убедить, что анемичная модель самая что ни на есть ООП. На это я и отвечал.

    ВВ>Да, в ОО-модели класс должен быть наделен поведением, а не представлять собой пустой набор геттеров и сеттеров. Это не значит, что ООП это хорошо или плохо. У ООП немало проблем и безотносительно к текущей теме. Но у ООП другие проблемы.
    ВВ>Какой смысл описывать откровенное убогое построение жирной модели — фактически доведенное до абсурда — и показывать, что это видите ли именно то, что жирная модель предполагает?
    У IB 90% статьи перпендекулярно самой идее Anemic Model, именно поэтому я тебя хотел пригласить в другой топик, где конкретно уже обсуждается Anemic Model, а не организация данных.

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

    Просто устроили детсад. Дурак -- сам дурак. Вроде взрослые люди, а все туда же.
  • Re[22]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 12:49
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Вот тут-то твое заблуждение.

    Это не мое заблуждение. Это ты опять с темы разговора съехать пытаешься.
    "А откуда берется правило, что в жирной модели если есть метод Save(), то туда надо непременно напихать все "что у нас есть"" — твои слова?
    Вот теперь отвечай, куда, по твоему, следует пихать "что у нас есть", при наличии метода Save() в объекте жирной модели.

    ВВ> Жирность модели вовсе не предполагает таких условий.

    Предполагает.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[22]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 12:49
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Он это объясняет довольно популярно.

    Он ничего не объясняет. Ты видимо тоже, берешь пример с великих.

    ВВ>И при этом мы все еще сомневаемся, что это не ОО модель?

    Мы уверены, что это ОО модель.

    ВВ>Нельзя.

    А кто запретит-то?

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

    А чем заложена невозможность изменения поведения?

    ВВ>Класс, а не данные. Order, Customer, etc. — это именно классы, обладающие поведением,

    Это данные, которые поведением не обладают и не должны.

    ВВ>А я не про наследование реализации. О чем кстати четко написано.

    Четко не написано ничего.. Я так и не смог от тебя добиться что же ты понимаешь под ОО, наследованием, "полиморфизм классов" и "родовые отношения"... Из чего делаю очевидный вывод, что ты все-таки просто потрепаться пришел..

    ВВ> Как он может быть более обобщен, когда "Правильны ответ — создавать новый сервис".

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

    ВВ>На остальное даже отвечать не хочется.

    То есть, по делу-то сказать тебе и нечего. Ни на один вопрос ты толком не ответил, в суть статьи не вник, модель твоя вообще полный ахтунг, как популярно показал Синклер, просто потрындеть захотелось и за Фаулера обидно. Что ж, понимаю..

    ВВ>Судя по всему, сказать тебе все-таки нечего. Что ж, жаль.

    Все что я хотел сказать, я сказал в обсуждаемом посте в блоге, и в ответах на конструктивную критику. То что от тебя конструктива не будет — было ясно с самого начала, так что, уж прости, утруждаться и бисер метать — не намерен, пока тольковые возражения не появятся.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[9]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 13:07
    Оценка:
    Здравствуйте, Ziaw, Вы писали:

    Z>1. Мы имеем то же самое решение, что и в rich, только в другом слое.

    И по факту оно менее многословное. Модель не нагружена pass-thru методами типа Save(IPersister)

    Z>3. Тут anemic не конкуренции. Однако это достоинство имеет обратную сторону, в сервисном подходе мы получаем очень жесткие связи между сервисами и рай для процедурного подхода. Либо раздутый набор самих сервисов.

    Почему? Сервисы отлично разруливаются через какие-нибудь IoC контейнеры или сервис-провайдеры.

    Z>офтопик: это похоже на холивар statefull vs stateless server, мы не имеем чистых реализаций ни того ни другого. Statefull проще превратить в унылое немасштабируемое г с проблемами интеграции.

    Я бы прямых параллелий не проводил, но что-то общее есть.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[3]: роль ООП при работе с данными
    От: Blazkowicz Россия  
    Дата: 26.11.08 14:20
    Оценка:
    Здравствуйте, IB, Вы писали:

    B>>Правильно ли я понимаю что в "стройной" модели таки планируется хранить значения PK в полях и коллекциях?

    IB>В целом да, за исключением вырожденых случаев.

    Пытаюсь представить себе такую систему во всех подробностях и вот какая заковыка получается. Не столько в самом подходе, сколько в существующих на сегодняшний день средствах сериализации и remoting. Особенно Web Service.
    Итак проблема вкратце: Клиент, Сервер, Web Service. Надо за один вызов вернуть как Order так и его Items. Но при этом, классы у нас не связаны. Большинство же современных средств в Java маппится на классы, в которых метод может вернуть только ссылку на один объект. Делать OrderWithItemsDTO никакого желания, естественно, нет. Это бы перечернуло достоинства "стройной" модели на раз. И вроде бы кажется что проткол это должено позволять, ведь нет проблемы в XML поместить Order, а за ним Items. Но вот строгая типизация SOAP как-то не позволяет. Один из выходов — все методы должны возвращать нетипизированый контейнер, в который будут свалены все сущности необходимые на клиенте. Не нравится.
    Другой выход — специальный сериализатор, который выдаст либо скушает стройный XML и свалки объектов. Но тут какая лажа всплывает. У нас теряется типизация. Вместо Order.List<Item> имеем Order.List<Integer>. Сериализатор никак не сможет самостоятельно разобратся что там именно Items. Мы, конечно, можем ему подсказать это через метаданные(аттрибуты\аннотации). Но это будет абсолютно уникальный сериализатор, который не даст нам использовать другие решения, заточные именно на сериализацию "тонкой" модели.

    Как планируется решать эту проблему? Очевидно, что ORM не единственный инструментарий, который требует от нас именно "жирной" модели данных.
    Re[21]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 14:51
    Оценка: -1
    Здравствуйте, Blazkowicz, Вы писали:

    ВВ>>Аргумент на самом деле простой — анемичная модель не объектно-ориентирована. Так считает Фаулер. Я с ним согласен.

    ВВ>>Анемичная модель лишает классы поведения. И это самое поведение, которое должно характеризовывать конкретную сущность выносится в отдельный слой, который представляет собой мешанину из "поведений" различных сущностей.
    B>Тут и далее мне мерещится одна ошибка в твоих рассуждениям. Мы говорим не про классы вообще, и реализацию систем в целом, а всего лишь про Domain Model и бизнес-логику.

    Мы говорим об ООП и его роли при работе с данными. Что собственно и вынесено в заголовок флейма.
    ООП при работе с данными ничем не отличается от ООП в любых других случаях. Это все тот же старый ООП, со всеми своими плюсами и минусами.

    ВВ>>
  • Так как поведение перестает быть частью самого объекта, то этот объект при желании можно наделить поведением, которое изначально не задумывалось для него, которое будет являться неправильным для этого объекта.
    B>Как минимум два контраргумента можно найти в дургих постах IB.
    B>- Anemic не отменяет поведения объекта, а лишь ограничивает его, для того чтобы минимизировать зависимости объекта.

    Ну вот у меня складывается ощущение, что отменяет. Опять-таки если рассматривать этот вопрос в том же ключе, что и Фаулер — то это тогда не будет анемичная модель. Хотите сервисы поверх доменной модели? Ради бога. Но не лишайте классы поведения.
    Собственно, все что я хочу сказать это то что жирная модель == ОО-модель. Не больше и не меньше. У жирной модели нет каких-либо особенных "фишек". Правила для ее построения — это правила построения ОО-модели. Точка. Ты с этим не согласен?

    B>У Фаулера, например, Domain зависит от Repository. Странно как-то.


    Мне кажется ты немножко неправильно понимаешь эту концепцию. Там есть отдельный лаер. Фактически мы имеем:

    User Interface

    Application

    Domain

    Infrastructure


    Последнее — это как раз то, где у нас может быть этот самый репозитори.
    Самый смысл то, что домен — это собственно бизнес. Типичная бизнес-логика. Инфрраструктура уже детали собственно сохранения, загрузки и проч. Каким образом организовать между ними взаимосвязь вопрос второстепенный. Можно, как я предлагал, на уровне Infrastructure реализовать шаблоны для персистенции и далее параметризовывать наши классы этими шаблонами. Это все детали. Никакой жесткой зависимости тут нет.

    Кстати, не доводилось ознакомиться с Domen Driven Design Эванса? Там мне кажется интересно проясняется этот вопрос.


    B>- Нет четкой методологии определения является то или иное поведение частью сущности. Так как существует множество пограничных вариантов.


    Нет четкой методологии даже для разделения на сущности. Это часть дизайна. Дизайн можно сделать хорошо и плохо. И разумеется не все действия с каким-нибудь Ордер должны являться частью непосредственно поведения Ордер.

    Like many people, I've come to reject the phased thinking of "design, then build." ... The really powerful domain models evolve over time, and even the most experienced modelers find that they gain their best ideas after the initial releases of a system.
    M. Fowler


    Тот факт, что классы должны обладать поведением наверное не стоит сводить к тому, что все возможные действия с этим классом надо пихать непосредственно в сам класс, не находишь?

    ВВ>>
  • Класс перестает быть полиморфным. Изменение поведения для этого класса предполагает изменение совершенно внешнего по отношению к нему сервиса. Наследование перестает быть средством изменения поведения. Код, работающий с нашим классом, также перестает быть обощенным. Для изменения поведения мне надо или править существующий сервис (в котором содержится код для других классов, а соответственно потенциально влиять и на него) или же создавать новый сервис. Для того, чтобы решить эту проблему мне придется поднимать совершенно отдельную модель сервисов — с наследованиями, разными реализациями и пр. — которая в итоге придет ровно к тем же проблемам, которые тут так остроумно находят у жирной модели.
    B>Наследование — зло в первом приближении. Наследование не должно изменять поведение, оно должно его расширять, если таковое имеется.

    ОК, принимаем уточнение. Должно расширять.

    B>Под "отдельной моделью" ты, наверное, имел ввиду "отдельную иерархию".


    Именно.

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


    В таком случае процесс — это тоже сущность. Почему нет? Вообще это проблемы конкретного ОО-дизайна, они есть, их никто не отрицает.

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


    Не надо вообще вводить такое понятие как "данные". Есть состояние сущности. Да и тот же "оформитель заказов" — разве у него не будет состояния?

    ВВ>>
  • "Контракт" для класса теряет свой смысл. В нем описываются только данные — не поведение. Контракт для работы с классом подменяется неким общим контрактом сервиса. Изменение, расширение поведения для одно класса приводит к изменению контракта для всего сервиса. Таким образом, изменение одной сущности косвенным образом затрагивает все сущности.
    B>Это всё верно, для классов. Но для построения модели предметной области не важно. И вывод у тебя ложный. Если я добавлю поле в класс Order и создам ExtendedOrder а так же обновлю сервис для использования этого нового класса, то это вообще никак не отразится на остальные сущности, используемые сервисом.

    Теоретически может отразиться. Точно также кстати IB строит критику жирной модели. Ведь мы же меняем сервис, в котором содержится логика и для других сущностей тоже. Кто гарантирует, что он не написан так, что мы затронет логику "соседних" сущностей?

    ВВ>>Контракт сервиса всегда изыбыточен.

    B>Спорное утверждение, ниразу не аргументированое нижеидущими выводами.

    Это замкнутый круг на самом деле
    Он избыточен с точки зрения ОО. Т.е. действия, которые он "выставляет", не являются, скажем так, "однородными", они объеденены не по "сущностному" критерию. Почему мы должны через единый сервис работать с заказами и с комплектующими для компьютером? Где критерии разбиения сервисов?
    Как только мы убираем принципы ОО, то сами начинаем творить из сервисов иерархию — да, она, конечно, не будет один-в-водин совпадать с иерархией классов,я несколько утрировал, но на самом деле она станет весьма приближена к ним.

    ВВ>>Он представляет собой километровую простыню методов, в которой ООП не больше, чем в коде на plain C образца 76 года. Мало того, что он будет постоянно изменяться, так и работать с ним просто-напросто неудобно.

    B>Практика показала что достаточно удобно.

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

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

    B>Это зависит от дизайна иерархии сервисов. И то что методы с друг другом не связаны это тоже отчасти верно.

    Отчасти неверно? Верно или нет, как ты абсолютно правильно сказал, "зависит от дизайна иерархии сервисов". Причем "практика показала", что хорошая иерархия сервисов где-то не так далеко по своей структуре от иерархии классов.

    ВВ>>Альтернатива — дробление одного сервиса на многие сервисы. Причем чем "легче" будет сервис, тем лучше это все будет выглядеть. В идеале мы придем к тому, что на каждый класс у нас будет по сервису. Занавес.

    B>Опять не верно. Так как поведение у нас внешнее для сущностей, то сервисы организуются совершенно не зависимо от иерархии модели данных.
    B>В том то и дело, если бы в идеале хоть раз получился сервис на класс, методы бы легко ложились на модель данных. Но в жизни так никогда не получается и сервисы имеют другую иерархию, если она вообще нужна.

    У тебя есть заказ. Есть оформитель заказов. Будет сервис ОформлениеЗаказа. Разве мы "далеко ушли"? По сути мы создаем еще одну абстракцию над абстракцией.

    ВВ>>Но он не настолько плох, как ту пытаются представить.

    B>Никто не говорит что ООП плох. Просто он не всегда удобен для реализации Domain Model. Особенно в трехзвенке.
    ВВ>>Это тянет на аргумент. Вспомни, чем ОО лучше структурного подхода. И здесь будет все тоже самое. Избавляясь от ООП, мы лишаемся всех его преимуществ.
    B>Подход не предлагает избавится от ООП повсеместно, а лишь в реализации Domain. И опять же не столько от самого ООП, сколько от проблем вызываных различным пониманием ООП.

    На настоящий момент мне кажется, что избавление от ООП в Домен Моделе фактически приводит к избавлению от Домен Модели. Возможно, я не прав, но низводя классы до храналищ данных, мы фактически нивелируем саму концепцию класса. Они у нас в сущности мало чем отличаются от "словарей" со свойствами.
    Зачем тогда вообще классы? Берите дата-сет, имеющий "реляционную" структуру.

    ВВ>>И вот, кстати, IB пытается убедить, что анемичная модель самая что ни на есть ООП. На это я и отвечал.

    ВВ>>Да, в ОО-модели класс должен быть наделен поведением, а не представлять собой пустой набор геттеров и сеттеров. Это не значит, что ООП это хорошо или плохо. У ООП немало проблем и безотносительно к текущей теме. Но у ООП другие проблемы.
    ВВ>>Какой смысл описывать откровенное убогое построение жирной модели — фактически доведенное до абсурда — и показывать, что это видите ли именно то, что жирная модель предполагает?
    B>У IB 90% статьи перпендекулярно самой идее Anemic Model, именно поэтому я тебя хотел пригласить в другой топик, где конкретно уже обсуждается Anemic Model, а не организация данных.

    У IB в статье критикуется жирная модель. Собственно, весь "флейм" начался с того, что я указал на то, что эта критика некорректна, и она приписывает жирной модели недостатки конкретной имплементации жирной модели (см. NHibernate).

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

    B>Просто устроили детсад. Дурак -- сам дурак. Вроде взрослые люди, а все туда же.

    Согласен .
    Но сдается мне, что я тут не единственный злодей. Неужели мой первоначальный пост был настолько обидным: http://rsdn.ru/Forum/Message.aspx?mid=3184789&amp;only=1
    Автор: Воронков Василий
    Дата: 23.11.08

    Хотя надо, конечно, работать над собой
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
  • Re[23]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 14:53
    Оценка:
    Здравствуйте, IB, Вы писали:

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


    ВВ>>Вот тут-то твое заблуждение.

    IB>Это не мое заблуждение. Это ты опять с темы разговора съехать пытаешься.
    IB>"А откуда берется правило, что в жирной модели если есть метод Save(), то туда надо непременно напихать все "что у нас есть"" — твои слова?
    IB>Вот теперь отвечай, куда, по твоему, следует пихать "что у нас есть", при наличии метода Save() в объекте жирной модели.

    В отдельный лаер.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[23]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 15:03
    Оценка:
    Здравствуйте, IB, Вы писали:

    ВВ>>Он это объясняет довольно популярно.

    IB>Он ничего не объясняет. Ты видимо тоже, берешь пример с великих.

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

    ВВ>>И при этом мы все еще сомневаемся, что это не ОО модель?

    IB>Мы уверены, что это ОО модель.

    Фаулер, сдается мне, понимает в ООП побольше тебя.

    ВВ>>Нельзя.

    IB>А кто запретит-то?

    sealed

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

    IB>А чем заложена невозможность изменения поведения?

    sealed

    ВВ>>Класс, а не данные. Order, Customer, etc. — это именно классы, обладающие поведением,

    IB>Это данные, которые поведением не обладают и не должны.

    Они обладают поведением. СделатьЗаказ — это поведение Кастомера.
    Если классы у нас не классы, а тупо данные — то наверное и вообще классы не нужны. Датасаты рулят.

    ВВ>>А я не про наследование реализации. О чем кстати четко написано.

    IB>Четко не написано ничего.. Я так и не смог от тебя добиться что же ты понимаешь под ОО, наследованием, "полиморфизм классов" и "родовые отношения"... Из чего делаю очевидный вывод, что ты все-таки просто потрепаться пришел..

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

    ВВ>> Как он может быть более обобщен, когда "Правильны ответ — создавать новый сервис".

    IB>Именно так и может. Сервис создается новый, а модель используется старая, обобщенная.

    А работаешь с ней через с новый сервис. Вся логика работы с "обобщенной" моделью куда идет?

    ВВ>>На остальное даже отвечать не хочется.

    IB>То есть, по делу-то сказать тебе и нечего. Ни на один вопрос ты толком не ответил, в суть статьи не вник, модель твоя вообще полный ахтунг, как популярно показал Синклер, просто потрындеть захотелось и за Фаулера обидно. Что ж, понимаю..

    Моя модель, которая "ахтунг", является примером реализации отдельного лаера персистенции, причем я сделал это так, чтобы, как тут хотели некоторые, по самому классу было видно куда он конкретно сохраняет. Я раз двести наверное сказал, что это наглядный пример. Тот факт, что вам это кажется "ахтунгом" очень живописно показывает уровень знакомства с материалом, который тут критикуется.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[4]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 15:44
    Оценка: +1
    Здравствуйте, Blazkowicz, Вы писали:

    B>Как планируется решать эту проблему?

    1. Все-таки в таких случаях большой DTO, агрегирующий все нужные данные, мне наиболее симпатичен. Такой сценарий возникает только тогда, когда надо выгрузить большей объем данных для оффлайновой работы. Это совершенно отдельный самостоятельный юз-кейс и логично, что под него нужен отдельный набор данных, тем более, что в этом наборе вполне себе переиспользуются структуры созданные ранее, под другие задачи. Более того, это уже не совсем DTO, так как в нем будут содержаться персистентные данные относящиеся непосредственно к синхронизации, типа таймстампов.
    2. В REST этой проблемы, по идее, нет.

    B>Очевидно, что ORM не единственный инструментарий, который требует от нас именно "жирной" модели данных.

    Инструментарии мне совершенно параллельны, мне интересны сценарии. А вот сценариев где "жирная" модель удобнее "стройной" очень мало. Скажем, в вышеприведенном "жирная" модель пролетает со свистом, так как просто некуда впихнуть те же таймстампы.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[22]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 15:44
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>ООП при работе с данными ничем не отличается от ООП в любых других случаях.

    Вопрос в том, как его применять.

    ВВ>Собственно, все что я хочу сказать это то что жирная модель == ОО-модель.

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

    ВВ>Правила для ее построения — это правила построения ОО-модели. Точка. Ты с этим не согласен?

    Так что же это за правила такие?
    Или ты намекаешь на то, что раз жирная модель в полный рост использует все внешние атрибуты ОО, то она ОО, а так как стройная этого не делает, то она уже не ОО?

    ВВ>Он избыточен с точки зрения ОО. Т.е. действия, которые он "выставляет", не являются, скажем так, "однородными",

    Из чего это следует?

    ВВ> они объеденены не по "сущностному" критерию.

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

    ВВ> Где критерии разбиения сервисов?

    Критерии функциональные.

    ВВ>Как только мы убираем принципы ОО,

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

    ВВ>Собственно, весь "флейм" начался с того, что я указал на то, что эта критика некорректна, и она приписывает жирной модели недостатки конкретной имплементации жирной модели (см. NHibernate).

    Ты так внимательно прочитал статью, что не заметил, что там нет ни слова про NH, но ринулся критиковать.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[22]: роль ООП при работе с данными
    От: Blazkowicz Россия  
    Дата: 26.11.08 16:13
    Оценка: +1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Мы говорим об ООП и его роли при работе с данными. Что собственно и вынесено в заголовок флейма.

    ВВ>ООП при работе с данными ничем не отличается от ООП в любых других случаях. Это все тот же старый ООП, со всеми своими плюсами и минусами.

    Жаль. Лично я надеялся что мы обсуждаем суть статьи: преимущества\недостатки Anemic Domain + Service а так же слабо связанные Domain данные в классах. А не всё шелуху вокруг типа EF, Hibernate, ООП и Фаулера.

    ВВ>Ну вот у меня складывается ощущение, что отменяет. Опять-таки если рассматривать этот вопрос в том же ключе, что и Фаулер — то это тогда не будет анемичная модель. Хотите сервисы поверх доменной модели? Ради бога. Но не лишайте классы поведения.

    Дело в том что их приходится лишать поведения по ряду причин. Одна из них банальна. Я не могу реюзать сущности Domain Model, когда их поведение вдруг требует работы с БД. Фалуер же предлагает как решение не stateless service, а Repository. Отсюда и масса вопросов. Почему? Ответы, потому что ООП, полиморфизм, наследование. А в ответ можно AOP, например противопоставить, который с Service и нужнее и удобнее. Именно поэтому как Фалеровский ООП, так и твои перечисления достоинств ООП никаким образом лично мне пока что преимушества не Rich перед Anemic не показали. У меня большой проект с Anemic Domain и всё там достаточно стройно. Страшно хочется больше конкретики.

    ВВ>Собственно, все что я хочу сказать это то что жирная модель == ОО-модель. Не больше и не меньше. У жирной модели нет каких-либо особенных "фишек". Правила для ее построения — это правила построения ОО-модели. Точка. Ты с этим не согласен?

    А с чем тут можно не соласится. Это и есть пересказывания Фаулера. Не Anemic == ООП. Да, точка.

    B>>У Фаулера, например, Domain зависит от Repository. Странно как-то.

    ВВ>Мне кажется ты немножко неправильно понимаешь эту концепцию. Там есть отдельный лаер. Фактически мы имеем:

    ВВ>

    ВВ>User Interface
    ВВ>-
    ВВ>Application
    ВВ>-
    ВВ>Domain
    ВВ>-
    ВВ>Infrastructure


    Ты как-то с высока на это дело смотришь. Мы здесь конкретно обсуждам Domain Model.

    ВВ>Последнее — это как раз то, где у нас может быть этот самый репозитори.

    ВВ>Самый смысл то, что домен — это собственно бизнес. Типичная бизнес-логика. Инфрраструктура уже детали собственно сохранения, загрузки и проч. Каким образом организовать между ними взаимосвязь вопрос второстепенный. Можно, как я предлагал, на уровне Infrastructure реализовать шаблоны для персистенции и далее параметризовывать наши классы этими шаблонами. Это все детали. Никакой жесткой зависимости тут нет.
    Весь этот абзац чудесно ложится как на Rich так и на Anemic, так что я вообще не понял к чем это.

    ВВ>Кстати, не доводилось ознакомиться с Domen Driven Design Эванса? Там мне кажется интересно проясняется этот вопрос.

    Нет не читал. Можешь тезисно сюда? Кроме отсылок к ООП?

    ВВ>Тот факт, что классы должны обладать поведением наверное не стоит сводить к тому, что все возможные действия с этим классом надо пихать непосредственно в сам класс, не находишь?

    Вот так мы и приходим к надобности Service layer, так как для многих операций у нас банально отсутствует класс предметной области. В связи с чем мы и выдумываем сущность Application/Service как то чье поведение мы описываем.

    ВВ>>>
  • Класс перестает быть полиморфным. Изменение поведения для этого класса предполагает изменение совершенно внешнего по отношению к нему сервиса. Наследование перестает быть средством изменения поведения. Код, работающий с нашим классом, также перестает быть
    B>>Тут что я ещё хочу отметить. Бизнес логика в подавляющем большинстве случаев не является поведением бизнес сущностей. А является процессом, который эти сущности использует.

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


    ВВ>Не надо вообще вводить такое понятие как "данные". Есть состояние сущности. Да и тот же "оформитель заказов" — разве у него не будет состояния?

    Тут уже вспомнили про состояние:
    http://rsdn.ru/forum/message/3189084.1.aspx
    Автор: Ziaw
    Дата: 26.11.08

    Есть над чем подумать.


    ВВ>Ведь мы же меняем сервис, в котором содержится логика и для других сущностей тоже. Кто гарантирует, что он не написан так, что мы затронет логику "соседних" сущностей?

    Это всего лишь вопрос к организации сервисов, а никак не аргумент против Anemic Model.


    ВВ>Он избыточен с точки зрения ОО. Т.е. действия, которые он "выставляет", не являются, скажем так, "однородными", они объеденены не по "сущностному" критерию. Почему мы должны через единый сервис работать с заказами и с комплектующими для компьютером? Где критерии разбиения сервисов?

    ВВ>Как только мы убираем принципы ОО, то сами начинаем творить из сервисов иерархию — да, она, конечно, не будет один-в-водин совпадать с иерархией классов,я несколько утрировал, но на самом деле она станет весьма приближена к ним.
    Повторяю. Не станет. Если бы всё так было здорово, я бы прям сейчас побежал все методы копировать из сервиса в бизнес сущности и даже заводить новые сущности. Но к сожалению сервисы удобнее привязывать к бизнес процессам. А не к модели отражающей модель в RDB.

    B>>Практика показала что достаточно удобно.

    ВВ>"Практика показала". Это неопровержимый аргумент. Прочитай начало записи в блоге, которая приводится по первой ссылке
    Точно такой же аргумент как "сделай ООП и будет ещё удобнее". Повторяю, в другом топике IB привет ряд аргументов в пользу сервисов\anemic, с которыми я абсолютно согласен. Но никто нигде больше мне не привел аргумента против, который бы мне стразу открыл мне глаза и показал ошибочность использования Anemic в моем проекте. Всё опять сводится к обсуждению того что ООП это круто. Ну не приходится мне выстраивать сложную иерахию из бизнес процессов. Ненадо они никому в отличие от данных. Отсюда и такая радикальная разница в организации данных от организации логики. Это исключительно про Domain, а не про данные и логику вообще.

    ВВ>Отчасти неверно? Верно или нет,

    Да. Опечатался. То что методы не связаны в сервисе это не верно.

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

    Нет, тут ты приплетаешь мне свои слова. Иерархие сервисов далеко от иерархии классов. Смотри выше.

    ВВ>У тебя есть заказ. Есть оформитель заказов. Будет сервис ОформлениеЗаказа. Разве мы "далеко ушли"? По сути мы создаем еще одну абстракцию над абстракцией.

    Почему ещё одну? Это из разных моделей абстракции.


    ВВ>На настоящий момент мне кажется, что избавление от ООП в Домен Моделе фактически приводит к избавлению от Домен Модели. Возможно, я не прав, но низводя классы до храналищ данных, мы фактически нивелируем саму концепцию класса. Они у нас в сущности мало чем отличаются от "словарей" со свойствами.

    И что? Пока что никто не обосновал почему это плохо.

    ВВ>Зачем тогда вообще классы? Берите дата-сет, имеющий "реляционную" структуру.

    За пределами Domain Model существует огромное количество другого кода уровня приложения, котрый использует ООП более чем активно. Но разговор пока только про Domain, достаточно не большую часть приложения в целом. Но важную. Датасеты не типизированы, для чего их сюда приплетать. Они никак не решат проблем с Rich Model.
  • Re[24]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 16:15
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>В отдельный лаер.

    Из каких соображений тогда Save() в БД содержится в объекте, а Save в XML — в отдельном слое?
    Кто первый встал, того и тапки?
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[24]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 26.11.08 16:15
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

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

    Я эту стаью читал еще в 2004, и с тех пор там ничего не поменялось, внятных объяснений не прибавилось.

    ВВ>Фаулер, сдается мне, понимает в ООП побольше тебя.

    В данном случае он этого не демонстрирует.

    IB>>А чем заложена невозможность изменения поведения?

    ВВ>sealed
    То есть, по делу сказать нечего. ЧТД.

    ВВ>Они обладают поведением. СделатьЗаказ — это поведение Кастомера.

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

    ВВ>Если классы у нас не классы, а тупо данные — то наверное и вообще классы не нужны.

    Странный вывод, ну и вообще, какой-то максимализм нездоровый..

    ВВ>Датасаты рулят.

    С датасетами отдельный разговор. Хочешь поговорить об этом?

    ВВ>Я пишу "наследование для изменения поведения", ты про "наследования для наследования реализации".

    Ты хочешь сказать, что наследование реализации не может использоваться для изменения поведения?

    ВВ>Я должен тут давать тебе определение наследования?

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

    ВВ>А работаешь с ней через с новый сервис.

    Именно.

    ВВ>Вся логика работы с "обобщенной" моделью куда идет?

    Не понял вопроса.

    ВВ> причем я сделал это так, чтобы, как тут хотели некоторые, по самому классу было видно куда он конкретно сохраняет.

    Где этого хотели?

    ВВ> Я раз двести наверное сказал, что это наглядный пример.

    Менее ахтунговым он от этого не становится..

    ВВ>Тот факт, что вам это кажется "ахтунгом" очень живописно показывает уровень знакомства с материалом, который тут критикуется.

    =) Он очень живописно показывает уровень твоего знакомства с материалом.
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[25]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 16:43
    Оценка:
    Здравствуйте, IB, Вы писали:

    ВВ>>В отдельный лаер.

    IB>Из каких соображений тогда Save() в БД содержится в объекте, а Save в XML — в отдельном слое?
    IB>Кто первый встал, того и тапки?

    Save в БД тоже во всем том же отдельном лаере. Почитай что-нибудь про model-driven design в конце концов.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[25]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 16:43
    Оценка:
    Здравствуйте, IB, Вы писали:

    ВВ>>Они обладают поведением. СделатьЗаказ — это поведение Кастомера.

    IB>Даже самые ярые защитники ООП в полный рост, сильно удивятся, когда обнаружат метод CreateOrder в классе Customer..

    Нда... Что тут сказать...
    Ну приведем другой примерчик:

    public class BrokerageAccount 
    {
        string AccountNumber { get; set; }
    
        string CustomerSocialSecurityNumber { get; set; }
    
        public Customer GetCustomer();
        
        public Investment GetInvestment();
    }
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[2]: роль ООП при работе с данными
    От: Кэр  
    Дата: 26.11.08 16:45
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>Да мы вообще положили прибор всей командой на следующие, простите, технологии:

    А>Linq, EF, SilverLight, WPF, WWF, ADO.NET Services, CardSpaces.

    Мои искренние соболезнования.

    А>Всё что для счастья надо это CLR, ADO.NET, WebServices, WinForms, WebForms, руки из плеч...

    А>и со временем будет Framework для своей предметной области...

    Скорее будет уродец, но свой заботливо выпестованный, а потому очень любимый. То что вы отмахиваетесь от Linq, EF, Silverligh, WPF — скорее всего говорит о том, что уродец уже есть.
    Re[2]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 26.11.08 17:30
    Оценка: +1
    Здравствуйте, Аноним, Вы писали:

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


    QL>>Заинтересовала статья: http://blogs.gotdotnet.ru/personal/bezzus/PermaLink.aspx?guid=7a6a69bd-bedf-425f-b09c-123b4a41f686


    А>Да мы вообще положили прибор всей командой на следующие, простите, технологии:

    А>Linq, EF, SilverLight, WPF, WWF, ADO.NET Services, CardSpaces.
    Молодцы, а объективные причины есть? или только незнание\страх ?

    А>Всё что для счастья надо это CLR, ADO.NET, WebServices, WinForms, WebForms, руки из плеч...

    А почему тогда на ассемблере не пишете?

    А>и со временем будет Framework для своей предметной области...

    Каждый разработчик должен хоть раз в жизни изобрести велосипед.
    Re[23]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 18:17
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Жаль. Лично я надеялся что мы обсуждаем суть статьи: преимущества\недостатки Anemic Domain + Service а так же слабо связанные Domain данные в классах. А не всё шелуху вокруг типа EF, Hibernate, ООП и Фаулера.


    Ну мои первоначальные посты действительно были не об этом. Я не против в общем-то обсудить и данный вопрос, хотя, честно говоря, не буду слишком хорошо чувствовать себя в шкуре чистого апологета жирной модели. Фактически здесь не существует silver bullet, а вот мнения конкретно о жирной модели, как показывает дискуссия, по каким-то причином сильно заниженные. Могу попробовать ее защитить

    ВВ>>Ну вот у меня складывается ощущение, что отменяет. Опять-таки если рассматривать этот вопрос в том же ключе, что и Фаулер — то это тогда не будет анемичная модель. Хотите сервисы поверх доменной модели? Ради бога. Но не лишайте классы поведения.

    B>Дело в том что их приходится лишать поведения по ряду причин. Одна из них банальна. Я не могу реюзать сущности Domain Model, когда их поведение вдруг требует работы с БД.

    Вот это и неправильно как раз. Я схемку внизу не случайно приводил. У тебя есть отдельный лаер с доменной моделью, там же содержится бизнес-логика. Над ним логика аппликейшина, в которой БЛ быть не должно. Строго под ним — собственно слой доступа к данным. Называть его можешь как хочешь — инфраструктура как у Эванса, репозиторий как у Фаулера — неважно.

    Итогом: Поведение сущности — это никак не логика доступа к данным, она отделена от сущности.

    ВВ>>Последнее — это как раз то, где у нас может быть этот самый репозитори.

    ВВ>>Самый смысл то, что домен — это собственно бизнес. Типичная бизнес-логика. Инфрраструктура уже детали собственно сохранения, загрузки и проч. Каким образом организовать между ними взаимосвязь вопрос второстепенный. Можно, как я предлагал, на уровне Infrastructure реализовать шаблоны для персистенции и далее параметризовывать наши классы этими шаблонами. Это все детали. Никакой жесткой зависимости тут нет.
    B>Весь этот абзац чудесно ложится как на Rich так и на Anemic, так что я вообще не понял к чем это.

    Ну не совсем. Здесь имеется в виду то, что бизнес-логика является непосредственной частью доменной модели. Она не в "сервисах".
    Представим, что у нас есть сущности Перевозка и Груз.

    Представим, что у нас есть некий метод — на данный момент даже неважно где он определен — БронироватьПеревозку:

    БронироватьПеревозку(Перевозка, Груз)
    (
    )


    Опять-таки неважно что там конкретно содержится. Закроем пока на это глаза. Там может и никакого дата-аксеса не быть, не в этом дело.
    Далее — на самом деле Груз не во всякую ведь Перевозку влезет. Т.е. нужно учитывать, что данная конкретная Перевозка способна вместить Груз. А ведь там еще и другой Груз может быть. А в требованиях у
    нас — тут самое интересное — также указано, что допустим, предположим, 10% перегруз.
    Теперь сущности выглядят так (упрощенно):

    Перевозка
    (
        Вместительность;
    )
    
    Груз
    (
        Размер;
    )


    Соответственно, в тот самый метод БронироватьПеревозку, который пока непонятно где, мы вставляем логику, которая проверяет есть ли, проще говоря, еще место (с учетом допустимого перегруза) для нашего Груза или уже места нет, и эта конкретная Перевозка нам не подходит. Этот метод может быть частью класса Перевозка, частью какого-нибудь сервиса DHL — неважно.
    Что плохого в этом подходе?
    Фактически у нас есть важное бизнес-правило, и оно смешано с каким-то другим кодом. А что ним надо делать? Куда его "засунуть"? Тут проблема даже не в том, что модификация этого правила на что-то там может повлиять и пр.
    Сам код внутри этого БронироватьПеревозку — на кого он расчитан? Бизнес-модель по нашей модели уже не построишь — упс. Программер — ну для этого это пару ифоф каких-то непонятных, что-то там на 1.1 помножается — не факт, что он вообще это соотнесет с каким-то правилом.

    Проблема тут в том, что это правило никак не отражено в нашей модели. Бизнес-правила это не отдельный BusinessRuleService — они должны читаться по модели. И они должны быть такими же сущностями, как и все остальное. Таким образом мы добавляем еще одну сущность:

    ПравилоПерегрузки
    (
      ПерегрузкаДопустима(Перевозка, Груз);
    )


    И да, да, это будет "класс", прям внутри которого, "по живому" будет описано наше бизнес-правило.
    Класс, естестественно, должен быть полиморфным — или через интерфейс, или через виртуальность. Захотим поменять правила перегрузки и разрешить, допустим, 20% перегруз — это коснется только сущности ПравилоПерегрузки.
    В итоге имеем то, что Перевозка, скажем, условно параметризуется правилом:

    Перевозка[ПравилоПерегрузки]
    (
      Вместительность;
      
      Бронировать(Груз);
    )


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

    В жирной — хотя какая "жирная" — в ООП — модели у нас будут Операторы, совершающие действия над Грузом, которые контролируются через Бизнес-Правила, представленные в виде отдельных сущностей (что и правильно — ведь не Оператор же правила работы с грузом устанавливает). Сама по себе модель будет содержать структуру рабочего процесса.

    А что окажется в случае с сервисами?

    ВВ>>Кстати, не доводилось ознакомиться с Domen Driven Design Эванса? Там мне кажется интересно проясняется этот вопрос.

    B>Нет не читал. Можешь тезисно сюда? Кроме отсылок к ООП?

    Ну я это и делаю потихоньку
    Полное название: Domain-Driven Design: Tackling Complexity in the Heart of Software, Eric Evans с предисловием Фаулера, которое я уже цитировал
    Ссылку приводить не буду, вроде не поощряется, но через гугл находится на раз-два.

    На самом деле к отсылкам к ООП стоит тоже относиться... ну менее критично как бы Они не тождественны "отсылкам на". Просто те же товарищи вроде Фаулера на самом деле имеют в виду, что вот у нас есть обширная практика использования ООП, мы все знаем, какие преимущества дает ООП и какие проблемы оно позволяет решить — вот и здесь, здесь ровно то же самое.

    ВВ>>Тот факт, что классы должны обладать поведением наверное не стоит сводить к тому, что все возможные действия с этим классом надо пихать непосредственно в сам класс, не находишь?

    B>Вот так мы и приходим к надобности Service layer, так как для многих операций у нас банально отсутствует класс предметной области. В связи с чем мы и выдумываем сущность Application/Service как то чье поведение мы описываем.

    Я неоднократно оговариваюсь, что на самом деле анемичная модель иногда действительно уместнее. При моем безграничном уважении к тов. Фаулеру, на к-м основано, можно, сказать мое понимание ООП.
    Да, есть сценарии, детерминированные теми же стейт-лесс сетевыми протоколами, когда стейт-лесс же сервис окажется тупо более "в кассу" чем все остальное. Но есть бесспорно и другие сценарии. И даже другие сетевые протоколы

    ВВ>>Ведь мы же меняем сервис, в котором содержится логика и для других сущностей тоже. Кто гарантирует, что он не написан так, что мы затронет логику "соседних" сущностей?

    B>Это всего лишь вопрос к организации сервисов, а никак не аргумент против Anemic Model.

    В том-то и суть — что в рамках любой концепции это всегда вопрос правильной организации иерархии классов. Это тупиковая ветка обсуждения на самом деле. Любая критика в сторону ОО-модели может также отметаться как "это лишь вопрос организации классов".

    B>>>Практика показала что достаточно удобно.

    ВВ>>"Практика показала". Это неопровержимый аргумент. Прочитай начало записи в блоге, которая приводится по первой ссылке
    B>Точно такой же аргумент как "сделай ООП и будет ещё удобнее". Повторяю, в другом топике IB привет ряд аргументов в пользу сервисов\anemic, с которыми я абсолютно согласен.

    К сожалению, других аргументов я не видел. А те которые видел показались не совсем, скажем так, правильными. Да и честно после Фаулера и Ко как-то совсем странно воспринмается такая трактовка ООП-модели.

    B>Но никто нигде больше мне не привел аргумента против, который бы мне стразу открыл мне глаза и показал ошибочность использования Anemic в моем проекте. Всё опять сводится к обсуждению того что ООП это круто. Ну не приходится мне выстраивать сложную иерахию из бизнес процессов. Ненадо они никому в отличие от данных. Отсюда и такая радикальная разница в организации данных от организации логики. Это исключительно про Domain, а не про данные и логику вообще.


    ВВ>>Отчасти неверно? Верно или нет,

    B>Да. Опечатался. То что методы не связаны в сервисе это не верно.

    Методы-действия связаны в сервисах не так как в ОО-модели. Не через сущности, которые осуществляют эти действия.

    ВВ>>На настоящий момент мне кажется, что избавление от ООП в Домен Моделе фактически приводит к избавлению от Домен Модели. Возможно, я не прав, но низводя классы до храналищ данных, мы фактически нивелируем саму концепцию класса. Они у нас в сущности мало чем отличаются от "словарей" со свойствами.

    B>И что? Пока что никто не обосновал почему это плохо.
    ВВ>>Зачем тогда вообще классы? Берите дата-сет, имеющий "реляционную" структуру.
    B>За пределами Domain Model существует огромное количество другого кода уровня приложения, котрый использует ООП более чем активно. Но разговор пока только про Domain, достаточно не большую часть приложения в целом. Но важную. Датасеты не типизированы, для чего их сюда приплетать. Они никак не решат проблем с Rich Model.

    Мне кажется датасеты — вообще некая концепция просто-контейнера-данных — является как бы следующим шагом в анемичной модели. Фактически логическим ее развитием.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[24]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 26.11.08 18:52
    Оценка: 2 (2)
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Ну не совсем. Здесь имеется в виду то, что бизнес-логика является непосредственной частью доменной модели. Она не в "сервисах".

    ВВ>Представим, что у нас есть сущности Перевозка и Груз.

    ВВ>Представим, что у нас есть некий метод — на данный момент даже неважно где он определен — БронироватьПеревозку:


    ВВ>
    ВВ>БронироватьПеревозку(Перевозка, Груз)
    ВВ>(
    ВВ>)
    ВВ>


    ВВ>Опять-таки неважно что там конкретно содержится. Закроем пока на это глаза. Там может и никакого дата-аксеса не быть, не в этом дело.

    ВВ>Далее — на самом деле Груз не во всякую ведь Перевозку влезет. Т.е. нужно учитывать, что данная конкретная Перевозка способна вместить Груз. А ведь там еще и другой Груз может быть. А в требованиях у
    ВВ>нас — тут самое интересное — также указано, что допустим, предположим, 10% перегруз.
    ВВ>Теперь сущности выглядят так (упрощенно):

    ВВ>
    ВВ>Перевозка
    ВВ>(
    ВВ>    Вместительность;
    ВВ>)
    
    ВВ>Груз
    ВВ>(
    ВВ>    Размер;
    ВВ>)
    ВВ>


    ВВ>Соответственно, в тот самый метод БронироватьПеревозку, который пока непонятно где, мы вставляем логику, которая проверяет есть ли, проще говоря, еще место (с учетом допустимого перегруза) для нашего Груза или уже места нет, и эта конкретная Перевозка нам не подходит. Этот метод может быть частью класса Перевозка, частью какого-нибудь сервиса DHL — неважно.

    Вроде все правильно.

    ВВ>Что плохого в этом подходе?

    ВВ>Фактически у нас есть важное бизнес-правило, и оно смешано с каким-то другим кодом. А что ним надо делать? Куда его "засунуть"? Тут проблема даже не в том, что модификация этого правила на что-то там может повлиять и пр.
    ВВ>Сам код внутри этого БронироватьПеревозку — на кого он расчитан? Бизнес-модель по нашей модели уже не построишь — упс. Программер — ну для этого это пару ифоф каких-то непонятных, что-то там на 1.1 помножается — не факт, что он вообще это соотнесет с каким-то правилом.
    Достаточно выделить метод с нормальным названием, который впоследствии можно сделать инжектируемым в сервис.


    ВВ>Проблема тут в том, что это правило никак не отражено в нашей модели. Бизнес-правила это не отдельный BusinessRuleService — они должны читаться по модели. И они должны быть такими же сущностями, как и все остальное.

    А что есть модель и почему бизнес-правила должны читаться по модели?

    ВВ>Таким образом мы добавляем еще одну сущность:



    ВВ>
    ВВ>ПравилоПерегрузки
    ВВ>(
    ВВ>  ПерегрузкаДопустима(Перевозка, Груз);
    ВВ>)
    ВВ>


    ВВ>И да, да, это будет "класс", прям внутри которого, "по живому" будет описано наше бизнес-правило.

    ВВ>Класс, естестественно, должен быть полиморфным — или через интерфейс, или через виртуальность. Захотим поменять правила перегрузки и разрешить, допустим, 20% перегруз — это коснется только сущности ПравилоПерегрузки.
    Тоже верно.

    ВВ>В итоге имеем то, что Перевозка, скажем, условно параметризуется правилом:

    ВВ>
    ВВ>Перевозка[ПравилоПерегрузки]
    ВВ>(
    ВВ>  Вместительность;
      
    ВВ>  Бронировать(Груз);
    ВВ>)
    ВВ>

    А почему сервис бронирования перевозки нельзя также параметризовать правилом перегрузки?

    Например так:
    СервисПеревозок
    {
        СервисПеревозок(ПравилоПерегрузки)
        (...)
    
        БронироватьПеревозку(Перевозка, Груз)
        (
            ...
            если ПравилоПерегрузки.ПерегрузкаДопустима(Перевозка, Груз) то
            ...
        )
    }


    Такой код дает:
    1)Меньшую связность — Перевозка не должна занать ни о Грузе, ни о ПравилеПерегрузки
    2)Возможность свободно менять правило перегрузки и сервис бронирования без перекомпиляции (через IoC)
    3)Не скрывает важные детали. В вашем случае Перевозка.Бронировать(Груз) вызывает может вызывать запросы к базе, обращения к удаленным сервисам или запуск workflow.
    Re[24]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 26.11.08 19:15
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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

    Действительно у груза может быть разное состояние\статус, которое выражается одним полем объекта.

    ВВ>причем всякий раз за действия с грузом отвечает разный оператор, действия, которые можно совершать над грузом, зависят от состояния Груза.

    Действительно мы можем создать workflow, в котором задаем различные этапы взаимодействия Оператора с Грузом.
    Отделяя при этом workflow от Оператора и Груза мы уменьшаем связывание и позволяем менять workflow без перекомпиляции.


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

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

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

    У нас нет какого-то единого процесса, у нас есть набор процессов (workflow), определяемый темиже бизнес-правилами в сервисах.
    То есть сервисы с правилами инжектируются в workflow.


    ВВ>В жирной — хотя какая "жирная" — в ООП — модели у нас будут Операторы, совершающие действия над Грузом, которые контролируются через Бизнес-Правила, представленные в виде отдельных сущностей (что и правильно — ведь не Оператор же правила работы с грузом устанавливает). Сама по себе модель будет содержать структуру рабочего процесса.

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

    ВВ>А что окажется в случае с сервисами?

    См выше.

    Кроме того, используя анемичную модель мы можем отказаться от DTO, так как в качестве DTO можем использовать сами объекты данных и составные объекты на базе них.
    Re[25]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 19:28
    Оценка: :)
    Здравствуйте, gandjustas, Вы писали:

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

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

    ВВ>>причем всякий раз за действия с грузом отвечает разный оператор, действия, которые можно совершать над грузом, зависят от состояния Груза.

    G>Действительно мы можем создать workflow, в котором задаем различные этапы взаимодействия Оператора с Грузом.
    G>Отделяя при этом workflow от Оператора и Груза мы уменьшаем связывание и позволяем менять workflow без перекомпиляции.

    "Уменьшаем связывания" я так посмотрю это какая-то мантра. Зачем мне действие, которое само по себе вводится некоторым субьектом, "отделять" от этого субьекта? Операции с Грузом на складе — это действия Оператора Склада.

    Причем операторы — они как бы разные. И каждый работает с грузом по-своему. Сколько тут всего будет workflow и как вы собираетесь их менять без перекомпиляции? Собственно, без перекомпиляции чего?
    А оператор, который хранит груз на складе, и оператор, который его перевозит еще и обладают разным набором характеристик, которые надо учитывать. И что в итоге получится? Сервис РаботаНаСкладе? Универсальная бизнес-логика прямо в нем прошита, чтобы "избежать перекомпиляции" видимо, в форме красиво названных методов? А потом СервисПеревозка? И еще какой-нибудь сервис.
    Тогда и получается — отдельная иерархия сервисов совпадающая с иерархией классов — как я и говорил. Или вы предлагаете работу разных операторов, которые не связаны друг с другом, в единый сервис зафигачить? Вот они удивятся, наверное

    Описывайте все-таки более конкретную архитектуру, а не общие слова — "ликвидируем связанность", "красиво названные методы", "изменения без перекомпляции" — тогда и обсудим. А пока советую чуть больше подумать над примером.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[26]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 26.11.08 20:09
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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


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

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

    ВВ>>>причем всякий раз за действия с грузом отвечает разный оператор, действия, которые можно совершать над грузом, зависят от состояния Груза.

    G>>Действительно мы можем создать workflow, в котором задаем различные этапы взаимодействия Оператора с Грузом.
    G>>Отделяя при этом workflow от Оператора и Груза мы уменьшаем связывание и позволяем менять workflow без перекомпиляции.

    ВВ>"Уменьшаем связывания" я так посмотрю это какая-то мантра.

    Конечно мантра. Уменьшение связности уменьшает сложность кода и стоимость внесения изменений.

    ВВ>Зачем мне действие, которое само по себе вводится некоторым субьектом, "отделять" от этого субьекта? Операции с Грузом на складе — это действия Оператора Склада.

    Это в жизни так. Не всегда модель реального мира стоит переносить на программу.
    Кроме того, Оператор.ОперацияСГрузом(Груз) всегда можно записать как ОперацияСГрузом(Оператор, Груз).
    Второй вариант предпочтительнее, ибо не вносит зависимость класса оператора от класса груза.

    ВВ>Причем операторы — они как бы разные. И каждый работает с грузом по-своему.

    И чем собственно операторы различаются?

    ВВ>Сколько тут всего будет workflow и как вы собираетесь их менять без перекомпиляции? Собственно, без перекомпиляции чего?

    Без перекомпиляции кода приложения. В идеале и без перезапуска приложения.

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

    А кто сказал что что нельзя использовать наследование?

    ВВ>И что в итоге получится? Сервис РаботаНаСкладе?

    Зависит от бизнес-задач.

    ВВ>Универсальная бизнес-логика прямо в нем прошита, чтобы "избежать перекомпиляции" видимо, в форме красиво названных методов? А потом СервисПеревозка? И еще какой-нибудь сервис.

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

    В случае жирной модели вместо сервиса РаботаНаСкладе, будут теже самые методы в сущности.


    ВВ>Тогда и получается — отдельная иерархия сервисов совпадающая с иерархией классов — как я и говорил.

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

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

    Не предлагаю, создайте несколько сервисов.

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

    "ликвидируем связанность" и "изменения без перекомпляции" — вполне конкретные преимущества.

    А что может жирная модель предложить, кроме мнимых достоинств?
    Re[27]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 26.11.08 21:52
    Оценка: 3 (1) -1
    Здравствуйте, gandjustas, Вы писали:

    ВВ>>"Уменьшаем связывания" я так посмотрю это какая-то мантра.

    G>Конечно мантра. Уменьшение связности уменьшает сложность кода и стоимость внесения изменений.

    "Уменьшение связности" надо делать там, где действительно не должно быть связности, а не трактовать lousely coupled как полную бессвязность. Согласны?

    ВВ>>Зачем мне действие, которое само по себе вводится некоторым субьектом, "отделять" от этого субьекта? Операции с Грузом на складе — это действия Оператора Склада.

    G>Это в жизни так. Не всегда модель реального мира стоит переносить на программу.
    G>Кроме того, Оператор.ОперацияСГрузом(Груз) всегда можно записать как ОперацияСГрузом(Оператор, Груз).
    G>Второй вариант предпочтительнее, ибо не вносит зависимость класса оператора от класса груза.

    Откуда вы ввзяли ОперацияСГрузом? ОперацияСГрузом — нет такой штуки. Есть РазместитьГрузНаСкладе, ПеревезтиСамолетом и пр. И знаете что — они все не зависят от класса груза ровно в той степени, в какой зависят от оператора. Независимо от того, внутри ли класса, сервиса или вообще в виду глобальной функции вы это опишите. Потому что владелец склада №526 не занимается авиа-перевозками.

    ВВ>>Причем операторы — они как бы разные. И каждый работает с грузом по-своему.

    G>И чем собственно операторы различаются?

    Чем отличается владелец склада №526 от Delta Airlines?

    ВВ>>Сколько тут всего будет workflow и как вы собираетесь их менять без перекомпиляции? Собственно, без перекомпиляции чего?

    G>Без перекомпиляции кода приложения. В идеале и без перезапуска приложения.

    Мне так и не понятно, что конкретно собираетесь менять.

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

    G>А кто сказал что что нельзя использовать наследование?

    А кто тут говорил про наследование?

    ВВ>>И что в итоге получится? Сервис РаботаНаСкладе?

    G>Зависит от бизнес-задач.
    ВВ>>Универсальная бизнес-логика прямо в нем прошита, чтобы "избежать перекомпиляции" видимо, в форме красиво названных методов? А потом СервисПеревозка? И еще какой-нибудь сервис.
    G>В чем проблема? Сложно назвать нормально методы и классы?

    Назвать — несложно. Но дело наверное не в названии.
    А в том, что бизнес-логика не должна быть ни частью сервиса, ни частью сущности. Бизнес-правило — отдельная сущность. Заметьте, это не я придумал
    Популярная тут в некоторых кругах критика жирной модели сводится к тому, что сами "структуры" данных вроде как меняются очень редко, тогда как поведение меняется часто. Это в корне неверено. Поведение сущностей не меняется никогда. Кошка не начнет лаять как собака, а владелец склада №526 не будет заниматься авиа-перевозками. Меняются — и действительно довольно часто — бизнес-правила — правило "перегрузки" контейнеров, правило для рождественской скидки. И сами по себе эти правила имеют внешний характер по отношению к сущностям. Они не только не являются их поведением, они вообще ни в каком смысле не являются их частью. Вы можете "указать" сущности какое правило ей нужно использовать, не более. Правило — на то и правило, что его все видели, что ему все следовали, а не прятали "в себе" и не притворялись, что это часть их поведения.

    Это была первая часть моего примера, где, заметьте, я вообще ничего не говорил про сервисы, не-сервисы. И это одно из важных оснований критики ОО-модели.

    G>В случае жирной модели вместо сервиса РаботаНаСкладе, будут теже самые методы в сущности.


    Да нет, не те же. Я вот например бизнес-логику в виде методов не предлагаю "инжектировать".

    ВВ>>Тогда и получается — отдельная иерархия сервисов совпадающая с иерархией классов — как я и говорил.

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

    А кто эти задачи решает? Они же не сами решаются. Вот есть задача — перевезти груз. Кто там это делает? А, Дельта Айрлаинс.

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

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

    Я так до сих пор не понял — что можете предложить лично вы. Я уже просил один раз, повторю еще.
    Мне непонятно то, о чем вы пишите. Это похоже на какие-то общие слова — какие-то workflow, низкая связанность, какие-то задачи уже поставлены вроде менять без перекомпиляции — при этом абсолютно неясно о чем конкретно речь.

    Опишите как будет выглядеть архитектура в свете представленного примера с грузом, вот тогда и будет что обсудить.
    Если конкретного описания не будет — то не обессудьте, продолжать дискуссию не буду.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[28]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 27.11.08 07:16
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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


    ВВ>>>"Уменьшаем связывания" я так посмотрю это какая-то мантра.

    G>>Конечно мантра. Уменьшение связности уменьшает сложность кода и стоимость внесения изменений.

    ВВ>"Уменьшение связности" надо делать там, где действительно не должно быть связности, а не трактовать lousely coupled как полную бессвязность. Согласны?

    Не согласен. К уменьшению связности надо стремиться всегда. Чем меньше связность — тем меньше сложность. Чем меньше связность, тем больше возможностей повтороного использования кода. Чем меньше связность, тем больше возможность изменять реализацию без остановки приложения.
    В каких случаях не надо уменьшать связность?

    ВВ>>>Зачем мне действие, которое само по себе вводится некоторым субьектом, "отделять" от этого субьекта? Операции с Грузом на складе — это действия Оператора Склада.

    G>>Это в жизни так. Не всегда модель реального мира стоит переносить на программу.
    G>>Кроме того, Оператор.ОперацияСГрузом(Груз) всегда можно записать как ОперацияСГрузом(Оператор, Груз).
    G>>Второй вариант предпочтительнее, ибо не вносит зависимость класса оператора от класса груза.

    ВВ>Откуда вы ввзяли ОперацияСГрузом? ОперацияСГрузом — нет такой штуки. Есть РазместитьГрузНаСкладе, ПеревезтиСамолетом и пр. И знаете что — они все не зависят от класса груза ровно в той степени, в какой зависят от оператора. Независимо от того, внутри ли класса, сервиса или вообще в виду глобальной функции вы это опишите. Потому что владелец склада №526 не занимается авиа-перевозками.


    ВВ>>>Причем операторы — они как бы разные. И каждый работает с грузом по-своему.

    G>>И чем собственно операторы различаются?
    ВВ>Чем отличается владелец склада №526 от Delta Airlines?
    Чем отличается? Давнными или поведением, или тем и другим?
    Если только поведением, то Опаератор — сервис в себе, если только данными, то все поведение можно вынести в отдельные сервисы. Если и тем и другим, то можно выделить полиморфное поведение для всех операторов и частное для различных операторов. Причем это будут не параллельные иерархии наследования. например РазместитьГрузНаСкладе будет в сервисе склада, а ПеревезтиСамолетом в сервисе перевозок.

    ВВ>>>Сколько тут всего будет workflow и как вы собираетесь их менять без перекомпиляции? Собственно, без перекомпиляции чего?

    G>>Без перекомпиляции кода приложения. В идеале и без перезапуска приложения.
    ВВ>Мне так и не понятно, что конкретно собираетесь менять.
    Бизнес-логику.

    ВВ>>>И что в итоге получится? Сервис РаботаНаСкладе?

    G>>Зависит от бизнес-задач.
    ВВ>>>Универсальная бизнес-логика прямо в нем прошита, чтобы "избежать перекомпиляции" видимо, в форме красиво названных методов? А потом СервисПеревозка? И еще какой-нибудь сервис.
    G>>В чем проблема? Сложно назвать нормально методы и классы?

    ВВ>Назвать — несложно. Но дело наверное не в названии.

    ВВ>А в том, что бизнес-логика не должна быть ни частью сервиса, ни частью сущности. Бизнес-правило — отдельная сущность. Заметьте, это не я придумал
    Какое-то странное понимание "сервиса". Сервис в данном случае — набор действий, которек выполняются с данными. Бизнес-правило — тоже сервис.

    ВВ>Популярная тут в некоторых кругах критика жирной модели сводится к тому, что сами "структуры" данных вроде как меняются очень редко, тогда как поведение меняется часто. Это в корне неверено.

    Доказательства?

    ВВ>Поведение сущностей не меняется никогда. Кошка не начнет лаять как собака, а владелец склада №526 не будет заниматься авиа-перевозками.

    В анемичной модели мы отказываемся от наделения данных поведением. У нас остаются бизнес-правила и бизнес-процессы. Правила и процессы вполне моделируются классами-сервисами.

    ВВ>Меняются — и действительно довольно часто — бизнес-правила — правило "перегрузки" контейнеров, правило для рождественской скидки. И сами по себе эти правила имеют внешний характер по отношению к сущностям. Они не только не являются их поведением, они вообще ни в каком смысле не являются их частью. Вы можете "указать" сущности какое правило ей нужно использовать, не более. Правило — на то и правило, что его все видели, что ему все следовали, а не прятали "в себе" и не притворялись, что это часть их поведения.

    Вот и получаются сервисы. Осталось отделить "поведение" от сущностей и вы получите анемичную модель.
    Причина отедлять "поведение" от данных — повторное использование модели данных.


    G>>В случае жирной модели вместо сервиса РаботаНаСкладе, будут теже самые методы в сущности.

    ВВ>Да нет, не те же. Я вот например бизнес-логику в виде методов не предлагаю "инжектировать".
    Ну да, логика будет жестко зашита в сущности. Это и есть сильная связность, что есть плохо.

    ВВ>>>Тогда и получается — отдельная иерархия сервисов совпадающая с иерархией классов — как я и говорил.

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

    ВВ>А кто эти задачи решает? Они же не сами решаются. Вот есть задача — перевезти груз. Кто там это делает? А, Дельта Айрлаинс.

    Ну и? В чем семантическая разница между ПеревезтиГруз(ДельтаАйрлаинс, Груз) и ДельтаАйрлаинс.ПеревезтиГруз(Груз). О том почему первый вариант лучше я уже писал.

    ВВ>Я так до сих пор не понял — что можете предложить лично вы. Я уже просил один раз, повторю еще.

    ВВ>Мне непонятно то, о чем вы пишите. Это похоже на какие-то общие слова — какие-то workflow, низкая связанность, какие-то задачи уже поставлены вроде менять без перекомпиляции — при этом абсолютно неясно о чем конкретно речь.

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

    ВВ>Если конкретного описания не будет — то не обессудьте, продолжать дискуссию не буду.
    Каковы решаемые задачи в этом примере и какова схема данных (хотябы примерно)?
    Re[26]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 27.11.08 07:39
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Save в БД тоже во всем том же отдельном лаере.

    Нет уж, ты от темы не увиливай, ты двавай за свои слова отвечай.
    Куда пихать второй Save, если первый не в отдельном?

    ВВ>Почитай что-нибудь про model-driven design в конце концов.

    Спорим, я больше умных слов знаю?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
    Мы уже победили, просто это еще не так заметно...
    Re[26]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 27.11.08 07:39
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Нда... Что тут сказать...

    Действительно, по делу-то тебе сказать и нечего.

    ВВ>Ну приведем другой примерчик:

    Это ты к чему?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
    Мы уже победили, просто это еще не так заметно...
    Re[24]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 27.11.08 07:39
    Оценка: +1 -1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Представим, что у нас есть сущности Перевозка и Груз.

    Пока, все это вполне себе стройная модель.

    ВВ>Фактически у нас есть важное бизнес-правило, и оно смешано с каким-то другим кодом.

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

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

    Вот тут я ход мысли, честно говоря, потерял.

    ВВ> Бизнес-правила это не отдельный BusinessRuleService — они должны читаться по модели.

    Почему они должны это делать и почему бизнес-правило не может быть отдельным BusinessRuleService?

    ВВ>
    ВВ>ПравилоПерегрузки
    ВВ>(
    ВВ>  ПерегрузкаДопустима(Перевозка, Груз);
    ВВ>)
    ВВ>

    Ну, чем это не сервис?... =)

    ВВ>Класс, естестественно, должен быть полиморфным — или через интерфейс, или через виртуальность. Захотим поменять правила перегрузки и разрешить, допустим, 20% перегруз — это коснется только сущности ПравилоПерегрузки.

    Для этого не нужен полиморфизм. Для этого надо ввести параметр МаксимальнаяПерегрузка и вынести его в модель, передав в сервис ПравилоПерегрузки при инстанцировании, например... Но в целом, да, такой сервис вполне может реализовывать какой-нибудь общий интерфейс.. )


    ВВ>
    ВВ>Перевозка[ПравилоПерегрузки]
    ВВ>(
    ВВ>  Вместительность;
      
    ВВ>  Бронировать(Груз);
    ВВ>)
    ВВ>

    Вот тут уже каша какая-то. Почему груз бронирует Перевозка, а не тот, кто отвечает за перевозку груза? Ну или наоборот, может это груз должен решать какой Перевозкой пользоваться? =)

    ВВ>Сама по себе модель будет содержать структуру рабочего процесса.

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

    ВВ>А что окажется в случае с сервисами?

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

    ВВ> При моем безграничном уважении к тов. Фаулеру, на к-м основано, можно, сказать мое понимание ООП.

    ОМГ.. Разбираться в ООП по Фаулеру — это все равно что основы общей физики по второму тому Ландавшица учить, понятно почему такая каша..

    ВВ> Да и честно после Фаулера и Ко как-то совсем странно воспринмается такая трактовка ООП-модели.

    Конечно, потому что в ОО надо разбираться не по Фаулеру и Ко.

    ВВ>Мне кажется датасеты — вообще некая концепция просто-контейнера-данных — является как бы следующим шагом в анемичной модели. Фактически логическим ее развитием.

    Наоборот, датасеты — это типичный пример жирной модели.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
    Мы уже победили, просто это еще не так заметно...
    Re[29]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 11:31
    Оценка: -1 :)
    Здравствуйте, gandjustas, Вы писали:

    ВВ>>"Уменьшение связности" надо делать там, где действительно не должно быть связности, а не трактовать lousely coupled как полную бессвязность. Согласны?

    G>Не согласен. К уменьшению связности надо стремиться всегда. Чем меньше связность — тем меньше сложность. Чем меньше связность, тем больше возможностей повтороного использования кода. Чем меньше связность, тем больше возможность изменять реализацию без остановки приложения.
    G>В каких случаях не надо уменьшать связность?

    Наверное в тех случаях, когда эта связь является сущностной характеристикой, первичным половым признаком, так сказать
    Какую вот связь вы хотите здесь устранить? Между Оператором и действием оператора? А что нам это даст?

    — Чтобы изменения в данных Оператора не затронули действие Оператора?
    А почему должна меняться структура данных у Дельты? С чего бы это вдруг? А если вдруг у Дельты появятся дополнительные атрибуты, новое состояние, которое будет стоить того, чтобы ради него менять соответствующй класс, вы уверены, что это не приведет к изменению действия? Я уверен, что приведет.

    — Чтобы изменения в действиях Оператора не затронули структуру данных Оператора?
    А какие могут быть изменения в действиях Оператора? Кошка "сменит пол" и начнет лаять? Дельта свернет свою лавочку и откроет сеть ресторанов "На девятом небе"? Ну тогда наверное мы вообще не сможет использовать ее как оператора. Будет летать Аэрофлотом

    ВВ>>>>Причем операторы — они как бы разные. И каждый работает с грузом по-своему.

    G>>>И чем собственно операторы различаются?
    ВВ>>Чем отличается владелец склада №526 от Delta Airlines?
    G>Чем отличается? Давнными или поведением, или тем и другим?

    Я бы сказал, что и данными тоже, вернее, даже не столько данными, сколько характеристиками состояния — ведь это такие разные вещи — хранить на складе и перевозить самолетом.

    G>Если только поведением, то Опаератор — сервис в себе,


    А можно по-подробнее? Как будет выглядеть этот сервис?

    G>если только данными, то все поведение можно вынести в отдельные сервисы. Если и тем и другим, то можно выделить полиморфное поведение для всех операторов и частное для различных операторов. Причем это будут не параллельные иерархии наследования. например РазместитьГрузНаСкладе будет в сервисе склада, а ПеревезтиСамолетом в сервисе перевозок.


    Ну т.е. на каждый тип оператора по сервису. К чему мы и пришли в итоге и на что Блажкович еще как-то пытался возражать. Есть иерархия операторов, а есть параллельная иерархия сервисов операторов.
    А чего мы этим добились, кстати?

    ВВ>>>>Сколько тут всего будет workflow и как вы собираетесь их менять без перекомпиляции? Собственно, без перекомпиляции чего?

    G>>>Без перекомпиляции кода приложения. В идеале и без перезапуска приложения.
    ВВ>>Мне так и не понятно, что конкретно собираетесь менять.
    G>Бизнес-логику.

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

    ВВ>>>>И что в итоге получится? Сервис РаботаНаСкладе?

    G>>>Зависит от бизнес-задач.
    ВВ>>>>Универсальная бизнес-логика прямо в нем прошита, чтобы "избежать перекомпиляции" видимо, в форме красиво названных методов? А потом СервисПеревозка? И еще какой-нибудь сервис.
    G>>>В чем проблема? Сложно назвать нормально методы и классы?

    ВВ>>Назвать — несложно. Но дело наверное не в названии.

    ВВ>>А в том, что бизнес-логика не должна быть ни частью сервиса, ни частью сущности. Бизнес-правило — отдельная сущность. Заметьте, это не я придумал
    G>Какое-то странное понимание "сервиса". Сервис в данном случае — набор действий, которек выполняются с данными. Бизнес-правило — тоже сервис.

    А у сервиса могут быть какие-то еще характеристики, кроме "набор действий"? Как мне понять, сервис это или не сервис? А том, может, у меня и правда одни сервисы кругом.
    Каковы правила изменения сервиса? Сервис может быть полиморфным в том же смысле, что и класс? Может ли сервис зависеть от других сервисов? А может ли сервис явно зависеть от каких-то структур данных в нашей Доменной Модели? Может ли сервис иметь состояние?

    Мне в общем-то по фигу как это называть. Мне важно не название, а то, где это бизнес-правило находится. А оно должно представлять собой отдельный класс. Структуры данных и действия не должны явно зависеть от бизнес-правила.

    ВВ>>Популярная тут в некоторых кругах критика жирной модели сводится к тому, что сами "структуры" данных вроде как меняются очень редко, тогда как поведение меняется часто. Это в корне неверено.

    G>Доказательства?

    Я доказательства привожу дальше вообще-то. Поведение — сущностная характеристика класса. Поведение определяет класс. Кошка может лаяться как собака?
    Придумайте сами пример, когда структура не менялась, а менялось поведение — и заодно посмотрите, действительно ли то, что изменялось является поведением.
    Типичная ошибка — это что-то типа — ИметьСкидку вставить как поведение для Товар. Естественно, это самое ИметьСкидку мы будет менять по 200 раз. Но какое же это поведение для Товар? Это бизнес-правило.

    ВВ>>Поведение сущностей не меняется никогда. Кошка не начнет лаять как собака, а владелец склада №526 не будет заниматься авиа-перевозками.

    G>В анемичной модели мы отказываемся от наделения данных поведением. У нас остаются бизнес-правила и бизнес-процессы. Правила и процессы вполне моделируются классами-сервисами.



    ВВ>>Меняются — и действительно довольно часто — бизнес-правила — правило "перегрузки" контейнеров, правило для рождественской скидки. И сами по себе эти правила имеют внешний характер по отношению к сущностям. Они не только не являются их поведением, они вообще ни в каком смысле не являются их частью. Вы можете "указать" сущности какое правило ей нужно использовать, не более. Правило — на то и правило, что его все видели, что ему все следовали, а не прятали "в себе" и не притворялись, что это часть их поведения.

    G>Вот и получаются сервисы. Осталось отделить "поведение" от сущностей и вы получите анемичную модель. Причина отедлять "поведение" от данных — повторное использование модели данных.

    Каким образом вы собираетесь использовать оператора авиа-перевозок независимо от его действий?

    G>>>В случае жирной модели вместо сервиса РаботаНаСкладе, будут теже самые методы в сущности.

    ВВ>>Да нет, не те же. Я вот например бизнес-логику в виде методов не предлагаю "инжектировать".
    G>Ну да, логика будет жестко зашита в сущности. Это и есть сильная связность, что есть плохо.

    Вы меня читаете вообще? Бизнес-логика представлена в виде отдельных сущностей. В сами классы защита та логика, которая не меняется по определению.

    ВВ>>>>Тогда и получается — отдельная иерархия сервисов совпадающая с иерархией классов — как я и говорил.

    G>>>Не получится, ибо методы в сервисы группируются по решаемым задачам, а не по субъекту действий.
    ВВ>>А кто эти задачи решает? Они же не сами решаются. Вот есть задача — перевезти груз. Кто там это делает? А, Дельта Айрлаинс.
    G>Ну и? В чем семантическая разница между ПеревезтиГруз(ДельтаАйрлаинс, Груз) и ДельтаАйрлаинс.ПеревезтиГруз(Груз).

    Это вы мне скажите, в чем разница. Оператор в первом и во втором случае — это одно и то же. Думаю, нет. Или одно и то же?
    Ведь оператор уже не может быть просто набором данных. У вас будет иерархия операторов, причем полиморфная, у операторов будет состояния. Осталось только вернуть им поведение — и это будет ОО-модель.

    G>О том почему первый вариант лучше я уже писал.


    А вы это покажите.

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

    ВВ>>Если конкретного описания не будет — то не обессудьте, продолжать дискуссию не буду.
    G>Каковы решаемые задачи в этом примере и какова схема данных (хотябы примерно)?

    Доставить груз из пункта А в пункт Б. Груз едет морем и воздухом, Груз надо страховать, хранить на складе в перерывах между перевозками. Есть бизнес-правило вокруг всего это, вроде допустимости 10% перегруза. Можете придумать сами. За каждое из действий отвечает отдельный оператор. Остальное можете додумать сами — неважно.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[30]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 27.11.08 12:23
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

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


    ВВ>>>"Уменьшение связности" надо делать там, где действительно не должно быть связности, а не трактовать lousely coupled как полную бессвязность. Согласны?

    G>>Не согласен. К уменьшению связности надо стремиться всегда. Чем меньше связность — тем меньше сложность. Чем меньше связность, тем больше возможностей повтороного использования кода. Чем меньше связность, тем больше возможность изменять реализацию без остановки приложения.
    G>>В каких случаях не надо уменьшать связность?

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

    ВВ>Какую вот связь вы хотите здесь устранить? Между Оператором и действием оператора? А что нам это даст?
    Возможность использовать объект оператора в тех частях системы, которые не должны знать о его поведении (например в клиентской части).

    ВВ>- Чтобы изменения в данных Оператора не затронули действие Оператора?

    ВВ>А почему должна меняться структура данных у Дельты? С чего бы это вдруг? А если вдруг у Дельты появятся дополнительные атрибуты, новое состояние, которое будет стоить того, чтобы ради него менять соответствующй класс, вы уверены, что это не приведет к изменению действия? Я уверен, что приведет.
    И пусть приведет. Изменение структуры данных практически всегда приводит к изменению практичечски всего кода вплоть до UI.

    ВВ>- Чтобы изменения в действиях Оператора не затронули структуру данных Оператора?

    ВВ>А какие могут быть изменения в действиях Оператора? Кошка "сменит пол" и начнет лаять? Дельта свернет свою лавочку и откроет сеть ресторанов "На девятом небе"? Ну тогда наверное мы вообще не сможет использовать ее как оператора. Будет летать Аэрофлотом
    Не надо демагогию разводить. Изменения могут быть любые.

    ВВ>>>>>Причем операторы — они как бы разные. И каждый работает с грузом по-своему.

    G>>>>И чем собственно операторы различаются?
    ВВ>>>Чем отличается владелец склада №526 от Delta Airlines?
    G>>Чем отличается? Давнными или поведением, или тем и другим?

    ВВ>Я бы сказал, что и данными тоже, вернее, даже не столько данными, сколько характеристиками состояния — ведь это такие разные вещи — хранить на складе и перевозить самолетом.

    Конкретнее. Какими характеристиками состояния?
    Я за этими "такими разными вещами" сейчас вижу только enum ShippingType.

    G>>Если только поведением, то Опаератор — сервис в себе,

    ВВ>А можно по-подробнее? Как будет выглядеть этот сервис?
    Все сервисы — классы, что непонятно? there is no magic

    G>>если только данными, то все поведение можно вынести в отдельные сервисы. Если и тем и другим, то можно выделить полиморфное поведение для всех операторов и частное для различных операторов. Причем это будут не параллельные иерархии наследования. например РазместитьГрузНаСкладе будет в сервисе склада, а ПеревезтиСамолетом в сервисе перевозок.


    ВВ>Ну т.е. на каждый тип оператора по сервису. К чему мы и пришли в итоге и на что Блажкович еще как-то пытался возражать. Есть иерархия операторов, а есть параллельная иерархия сервисов операторов.

    ВВ>А чего мы этим добились, кстати?
    См выделенное. Методы в сервисы группируются по другим признакам.


    G>>Какое-то странное понимание "сервиса". Сервис в данном случае — набор действий, которек выполняются с данными. Бизнес-правило — тоже сервис.


    ВВ>А у сервиса могут быть какие-то еще характеристики, кроме "набор действий"? Как мне понять, сервис это или не сервис? А том, может, у меня и правда одни сервисы кругом.

    Наверное тебе стоит почитать про SOA.

    ВВ>Каковы правила изменения сервиса? Сервис может быть полиморфным в том же смысле, что и класс?

    Да, сервис — это класс.

    ВВ>Может ли сервис зависеть от других сервисов?

    Да.

    ВВ>А может ли сервис явно зависеть от каких-то структур данных в нашей Доменной Модели?

    Он будет явно зависить он них, почтому что выполняет какие-то действия с данными. А данные не будут зависить от сервисов.

    ВВ>Может ли сервис иметь состояние?

    Может.

    ВВ>Мне в общем-то по фигу как это называть. Мне важно не название, а то, где это бизнес-правило находится. А оно должно представлять собой отдельный класс. Структуры данных и действия не должны явно зависеть от бизнес-правила.

    Почему действия не должны зависеть от бизнес-правил? Сам же выше приводил пример с такой зависимостью.

    ВВ>>>Популярная тут в некоторых кругах критика жирной модели сводится к тому, что сами "структуры" данных вроде как меняются очень редко, тогда как поведение меняется часто. Это в корне неверено.

    G>>Доказательства?

    ВВ>Я доказательства привожу дальше вообще-то. Поведение — сущностная характеристика класса. Поведение определяет класс. Кошка может лаяться как собака?

    У нас не кошки и собаки. Прочитай название темы.

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

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


    ВВ>Типичная ошибка — это что-то типа — ИметьСкидку вставить как поведение для Товар. Естественно, это самое ИметьСкидку мы будет менять по 200 раз. Но какое же это поведение для Товар? Это бизнес-правило.

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


    ВВ>Каким образом вы собираетесь использовать оператора авиа-перевозок независимо от его действий?

    Например в отчете выводить его название или при оплате получать стоимость перевозки.

    G>>>>В случае жирной модели вместо сервиса РаботаНаСкладе, будут теже самые методы в сущности.

    ВВ>>>Да нет, не те же. Я вот например бизнес-логику в виде методов не предлагаю "инжектировать".
    G>>Ну да, логика будет жестко зашита в сущности. Это и есть сильная связность, что есть плохо.

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

    Это какая логика "не меняектся по-определению"? Только тривиальная, типа получить сумму по цене и количеству. Любая нетривиальная логика изменится не один раз.

    ВВ>>>>>Тогда и получается — отдельная иерархия сервисов совпадающая с иерархией классов — как я и говорил.

    G>>>>Не получится, ибо методы в сервисы группируются по решаемым задачам, а не по субъекту действий.
    ВВ>>>А кто эти задачи решает? Они же не сами решаются. Вот есть задача — перевезти груз. Кто там это делает? А, Дельта Айрлаинс.
    G>>Ну и? В чем семантическая разница между ПеревезтиГруз(ДельтаАйрлаинс, Груз) и ДельтаАйрлаинс.ПеревезтиГруз(Груз).

    ВВ>Это вы мне скажите, в чем разница. Оператор в первом и во втором случае — это одно и то же. Думаю, нет. Или одно и то же?

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

    ВВ>Ведь оператор уже не может быть просто набором данных. У вас будет иерархия операторов, причем полиморфная, у операторов будет состояния. Осталось только вернуть им поведение — и это будет ОО-модель.

    Действительно. А не возвращать им поведение и будет стройная модель.

    G>>О том почему первый вариант лучше я уже писал.

    ВВ>А вы это покажите.
    Показать почему меньшая связность — лучше?
    Это должен быть достаточно большой проект. "На пальцах" не получится.

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

    ВВ>>>Если конкретного описания не будет — то не обессудьте, продолжать дискуссию не буду.
    G>>Каковы решаемые задачи в этом примере и какова схема данных (хотябы примерно)?

    ВВ>Доставить груз из пункта А в пункт Б. Груз едет морем и воздухом, Груз надо страховать, хранить на складе в перерывах между перевозками. Есть бизнес-правило вокруг всего это, вроде допустимости 10% перегруза. Можете придумать сами. За каждое из действий отвечает отдельный оператор. Остальное можете додумать сами — неважно.

    Детали тут — как раз самое важное. При проектировании сферического коня в вакууме ничего хорошего не получается.


    После таких уверенных рассказов про операторов и грузы могу предположить что есть готовая система, покажите здесь код и обсудим на конкретных примерах.
    Re[31]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 15:03
    Оценка: +1 -1 :)
    Здравствуйте, gandjustas, Вы писали:

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

    ВВ>>Какую вот связь вы хотите здесь устранить? Между Оператором и действием оператора? А что нам это даст?
    G>Возможность использовать объект оператора в тех частях системы, которые не должны знать о его поведении (например в клиентской части).

    Зачем нужно использовать Оператора, введенного ради его поведения, без знания о его поведении? И что конкретно там будет использоваться? Если общие данные об операторе, то для этого вполне подходит супер-класс Оператор.

    ВВ>>- Чтобы изменения в действиях Оператора не затронули структуру данных Оператора?

    ВВ>>А какие могут быть изменения в действиях Оператора? Кошка "сменит пол" и начнет лаять? Дельта свернет свою лавочку и откроет сеть ресторанов "На девятом небе"? Ну тогда наверное мы вообще не сможет использовать ее как оператора. Будет летать Аэрофлотом
    G>Не надо демагогию разводить. Изменения могут быть любые.

    Демагогию разводите вы. Ничего конкретного я так и слышу. Чтобы отвечать в вашем стиле, достаточно заучить несколько общих фраз и отвечать, комбинируя их в разном порядке.
    Изменения в действиях субьекта по определению не могут быть независимыми от структуры субьекта. Если они независимы — значит неправильно выделен субьект.

    ВВ>>Я бы сказал, что и данными тоже, вернее, даже не столько данными, сколько характеристиками состояния — ведь это такие разные вещи — хранить на складе и перевозить самолетом.

    G>Конкретнее. Какими характеристиками состояния?
    G>Я за этими "такими разными вещами" сейчас вижу только enum ShippingType.

    Т.е. отличие между Оператором, хранящим груз на складе, и Оператором, перевозящим груз, это "enum ShippingType"?

    G>>>Если только поведением, то Опаератор — сервис в себе,

    ВВ>>А можно по-подробнее? Как будет выглядеть этот сервис?
    G>Все сервисы — классы, что непонятно? there is no magic

    Да, теперь все понятно

    ВВ>>Ну т.е. на каждый тип оператора по сервису. К чему мы и пришли в итоге и на что Блажкович еще как-то пытался возражать. Есть иерархия операторов, а есть параллельная иерархия сервисов операторов.

    ВВ>>А чего мы этим добились, кстати?
    G>См выделенное. Методы в сервисы группируются по другим признакам.

    Да, я уже услышал этот великий признак. Только вот все примеры сервисов, которые приводятся, почему-то совпадают с иерархией классов. Сервисы группируются по решаемым задачам, да? А кто решает задачи?

    ВВ>>А у сервиса могут быть какие-то еще характеристики, кроме "набор действий"? Как мне понять, сервис это или не сервис? А том, может, у меня и правда одни сервисы кругом.

    G>Наверное тебе стоит почитать про SOA.

    Наверное, стоит перестать хамить и подумать, почему бизнес-правило это не сервис. А я про SOA я знаю побольше вашего.

    ВВ>>Каковы правила изменения сервиса? Сервис может быть полиморфным в том же смысле, что и класс?

    G>Да, сервис — это класс.

    Нет.

    ВВ>>Может ли сервис зависеть от других сервисов?

    G>Да.

    Нет.

    ВВ>>А может ли сервис явно зависеть от каких-то структур данных в нашей Доменной Модели?

    G>Он будет явно зависить он них, почтому что выполняет какие-то действия с данными. А данные не будут зависить от сервисов.

    Нет.

    ВВ>>Может ли сервис иметь состояние?

    G>Может.

    Нет.
    Может быть вам стоит прочитать про SOA?

    ВВ>>Мне в общем-то по фигу как это называть. Мне важно не название, а то, где это бизнес-правило находится. А оно должно представлять собой отдельный класс. Структуры данных и действия не должны явно зависеть от бизнес-правила.

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

    Действия определяются бизнес-правилами. Это разные вещи. "Купить товар" и "получить скидку".

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

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

    Это не поведение, это бизнес-логика.

    G>В жирной модели приедтся сущность Перевозка дополнить парамертрами аппрувов,


    Нет, придется определить новое бизнес-правило.

    Остальные мудрствования поскипаны. Больше писать в этом топике не буду.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[32]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 27.11.08 15:15
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

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


    ВВ>>>- Чтобы изменения в действиях Оператора не затронули структуру данных Оператора?

    ВВ>>>А какие могут быть изменения в действиях Оператора? Кошка "сменит пол" и начнет лаять? Дельта свернет свою лавочку и откроет сеть ресторанов "На девятом небе"? Ну тогда наверное мы вообще не сможет использовать ее как оператора. Будет летать Аэрофлотом
    G>>Не надо демагогию разводить. Изменения могут быть любые.

    ВВ>Демагогию разводите вы. Ничего конкретного я так и слышу. Чтобы отвечать в вашем стиле, достаточно заучить несколько общих фраз и отвечать, комбинируя их в разном порядке.

    ВВ>Изменения в действиях субьекта по определению не могут быть независимыми от структуры субьекта. Если они независимы — значит неправильно выделен субьект.
    Контр-пример. Изменение порядка бронирования груза. от самого руза никак не зависит.

    ВВ>>>Я бы сказал, что и данными тоже, вернее, даже не столько данными, сколько характеристиками состояния — ведь это такие разные вещи — хранить на складе и перевозить самолетом.

    G>>Конкретнее. Какими характеристиками состояния?
    G>>Я за этими "такими разными вещами" сейчас вижу только enum ShippingType.

    ВВ>Т.е. отличие между Оператором, хранящим груз на складе, и Оператором, перевозящим груз, это "enum ShippingType"?

    В таком случае это 2 разных набора данных: "склад" и "перевозчик" или два разных сервиса.


    ВВ>>>Ну т.е. на каждый тип оператора по сервису. К чему мы и пришли в итоге и на что Блажкович еще как-то пытался возражать. Есть иерархия операторов, а есть параллельная иерархия сервисов операторов.

    ВВ>>>А чего мы этим добились, кстати?
    G>>См выделенное. Методы в сервисы группируются по другим признакам.

    ВВ>Да, я уже услышал этот великий признак. Только вот все примеры сервисов, которые приводятся, почему-то совпадают с иерархией классов.

    Какие примеры?

    ВВ>Сервисы группируются по решаемым задачам, да? А кто решает задачи?

    Сервисы и решают.

    ВВ>>>А у сервиса могут быть какие-то еще характеристики, кроме "набор действий"? Как мне понять, сервис это или не сервис? А том, может, у меня и правда одни сервисы кругом.

    G>>Наверное тебе стоит почитать про SOA.

    ВВ>Наверное, стоит перестать хамить и подумать, почему бизнес-правило это не сервис. А я про SOA я знаю побольше вашего.

    И в чем же разница между бизнес-правилом и сервисом?

    ВВ>>>Каковы правила изменения сервиса? Сервис может быть полиморфным в том же смысле, что и класс?

    G>>Да, сервис — это класс.
    ВВ>Нет.
    ?

    ВВ>>>Может ли сервис зависеть от других сервисов?

    G>>Да.
    ВВ>Нет.
    И кто-то после этого говорит что понимает SOA?

    ВВ>>>А может ли сервис явно зависеть от каких-то структур данных в нашей Доменной Модели?

    G>>Он будет явно зависить он них, почтому что выполняет какие-то действия с данными. А данные не будут зависить от сервисов.
    ВВ>Нет.
    Совсем бред. Как сервисы могут что-то делать с данными если ничего о них не знают?

    ВВ>>>Может ли сервис иметь состояние?

    G>>Может.
    ВВ>Нет.
    Причины?

    ВВ>Может быть вам стоит прочитать про SOA?

    Улыбнуло.

    ВВ>>>Мне в общем-то по фигу как это называть. Мне важно не название, а то, где это бизнес-правило находится. А оно должно представлять собой отдельный класс. Структуры данных и действия не должны явно зависеть от бизнес-правила.

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

    ВВ>Действия определяются бизнес-правилами. Это разные вещи. "Купить товар" и "получить скидку".

    и какая разница с точки зрения программы?

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

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

    ВВ>Это не поведение, это бизнес-логика.

    А что тогда "поведение", чем оно отличается "бизнес-логики", чем они отличаются от "бизнес-правил"?
    С точки зрения программы. Концептуальные вещи не интересуют.

    G>>В жирной модели приедтся сущность Перевозка дополнить парамертрами аппрувов,

    ВВ>Нет, придется определить новое бизнес-правило.
    Правильно, а как код, который бронирует груз узнает о новом бизнес-правиле?
    Re[32]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 27.11.08 15:17
    Оценка: -1
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Остальные мудрствования поскипаны. Больше писать в этом топике не буду.

    Слив засчитан.
    Re[33]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 15:29
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    ВВ>>Может быть вам стоит прочитать про SOA?

    G>Улыбнуло.

    Почитайте МСДН хотя бы, чтобы в следующий раз свое невежество так не выказывать:
    http://msdn.microsoft.com/en-us/library/ms954638.aspx

    Кстати, было бы очень интересно посмотреть на сервис, зависящий от типов в конкретной Доменной Модели
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[34]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 27.11.08 17:40
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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


    ВВ>>>Может быть вам стоит прочитать про SOA?

    G>>Улыбнуло.

    ВВ>Почитайте МСДН хотя бы, чтобы в следующий раз свое невежество так не выказывать:

    ВВ>http://msdn.microsoft.com/en-us/library/ms954638.aspx
    Вау, круто. Вообще-то SOA гораздо шире, чем веб-сервисы.

    ВВ>Кстати, было бы очень интересно посмотреть на сервис, зависящий от типов в конкретной Доменной Модели

    В случае анемичной модели типы в ней описывают только данные.
    Теперь вопрос, может ли сервис что-то делать с данными если он о них ничего не знает?
    Re[5]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 19:20
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

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


    ST>>Если дела обстоят именно так, как Вы описываете, тогда действительно, делать Order.Items свойством — это ошибка проектирования.


    S>>>Все эти полезные подробности, вытекающие из удаленного характера Items, скрыты за тупым геттером.

    ST>>См. выше. Однако, рассмотрите также и ситуацию, когда Ордер.Айтемс — это именно свойство Ордер. С семантикой свойства. Ни один Айтем без заказа не существует. Удаляются они все вместе. Ну и так далее. Скажите, в таком случае отложенная загрузка — тоже плохо?
    S>Естественно. Совершенно неважно, что айтемы не могут жить без ордера.
    S>Во-первых, это неправда — в топике Иван приводил, почему. В частности, менеджера поставок вообще не интересует, в каких заказах расположены айтемы.
    S>С его точки зрения, айтемы принадлежат товару.

    Так это же преимущество доменной модели. В отличии от анемичной, она вообще не завист от БД. Это более чем нормально строить отдельные доменные области для разныех областей применения промапленные на одни и теже физичиские данные. Если есть описанный рекваирмент, то вообще не проблема создать одну модель для склада (ордер и чаилдами ввиде ордер айтемс) и вторую для менеджера (товар, а к ниму ридонли прилинкованы ордер айтмс).

    Более того в анемичной такая схема выходит значительно сложней. Я думаю вам легко будет представить себе модель в которой ордер айтемс для модели склада значительно отличаеться от ордер айтмс для менеджера.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[9]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 19:20
    Оценка: -1 :))
    Здравствуйте, Ziaw, Вы писали:

    Z>Реально из недостатков rich модели я могу пречислить следующие:


    Z>1. Бизнесметоды меняются и нам приходится иногда держать несколько вариантов одного и того-же бизнесметода в модели. Решается стратегией. В примере Save() добавляем метод Save(IPersister persister). Save() объявляем депрекейтед и сокращаем его использование до минимума.


    Странно что все приколупались к этому методу Save. В доменных моделях уже давно практикуеться паттерн репозитарий. Упрощенно это класс уровня бизнеслогики который управляет сохранением и доставанием сущности откуданибыло. Важно понимать что он упровляет. Тоесть реально работу выполняет стандарный ДАЛ. Вобщемто применение этого паттерна сразу же убивает наповал аргумент автора статьи по поводу сохранения в БД/сериализации. Точно также он убивает агрумент про SRP. А еще в отличии от анмеичных моделей этот паттерн четко отвечает на вопрос как мне заперсистить сущность. И все на одном слое. И все понятно по коду.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[21]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 19:20
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>- Anemic не отменяет поведения объекта, а лишь ограничивает его, для того чтобы минимизировать зависимости объекта. У Фаулера, например, Domain зависит от Repository. Странно как-то.


    Репозитарий Фаулера(точнее даже Ерика Еванса) это часть бизнеслогики.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[5]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 20:02
    Оценка: +1 -2 :)
    Здравствуйте, IB, Вы писали:

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


    B>>Как планируется решать эту проблему?

    IB>1. Все-таки в таких случаях большой DTO, агрегирующий все нужные данные, мне наиболее симпатичен. Такой сценарий возникает только тогда, когда надо выгрузить большей объем данных для оффлайновой работы.
    Такой сценарий возникает всегда. От обьема данных это не зависит. У кастомера — адреса, у ордера — айтемы.
    IB>Это совершенно отдельный самостоятельный юз-кейс и логично, что под него нужен отдельный набор данных, тем более, что в этом наборе вполне себе переиспользуются структуры созданные ранее, под другие задачи.
    Нет, например глупо выгружать на клинет внутренние айдишники оредер айтемов (тех что от ордера)? Да и вы сами дальше говорите про таймстампы. Или у вас в "стройной" моделе будут еще и таимстампы? И вообще что это за фишка внутреннюю модель системы показывать как публичный контракт? Типа для изменениня бизнеспроцеса поменть версию публичного контракта? Ндя.
    IB> Более того, это уже не совсем DTO, так как в нем будут содержаться персистентные данные относящиеся непосредственно к синхронизации, типа таймстампов.
    IB>2. В REST этой проблемы, по идее, нет.
    Ну и казалось причем тут РЕСТ и синхронизация?

    B>>Очевидно, что ORM не единственный инструментарий, который требует от нас именно "жирной" модели данных.

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

    Иначе говоря над жирными моделями всегда есть фасады. А фасады возвращают ДТО. Будет ли это ремот фасад или просто сервис лэер роли не играет. У нас уже есть ДТО с достаточным уровнем деталиации. Никуда вобщемто жирная модель не пролитает.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[22]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 20:55
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    MC>Репозитарий Фаулера(точнее даже Ерика Еванса) это часть бизнеслогики.


    Вообще-то это совсем не так. Эванс как раз настаивает на выделении Домен Модели от всего остального (в т.ч. числе и от "инфраструктуры" или "репозитория") именно как центрального слоя бизнес-логики.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[23]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 21:50
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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


    MC>>Репозитарий Фаулера(точнее даже Ерика Еванса) это часть бизнеслогики.


    ВВ>Вообще-то это совсем не так. Эванс как раз настаивает на выделении Домен Модели от всего остального (в т.ч. числе и от "инфраструктуры" или "репозитория") именно как центрального слоя бизнес-логики.


    Вообще-то это именно так . Репозитарий это часть доменной модели. Если смотреть это с точки зрения реальных вещей, то это папка с ордерами. Ну а уже то как она реализована эта папка моделлеров не интересует. Репозитарий может обращаться к выделенному ДАЛ, а может быть постороен на ОРМ.

    Посмотрите на http://dddsample.sourceforge.net/ это офциальный пример. Посмтрите где располгаються и как располагаються репозитарии. Обратите внимание что они работают с обьектами модели, если бы это был ДАЛ он бы возвращал рекорды(ДТО).

    Или например почитайте тут — http://fragmental.tw/2007/11/29/repositories-misunderstandings/

    Или саму книгу. Вы найдете там упоминания про виртуальные колекции и тому подобное. Это все не характеристики ДАЛ. И они не выносятся на другой слой.

    Хорошый список заблужений включая и это есть на http://tech.groups.yahoo.com/group/domaindrivendesign/. На него обычно ссылаються когда задают вопросы по типу можно ли ссылаться из модели на репозатарии. Но к сожалению я не могу его найти.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[24]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 22:11
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

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


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


    MC>>>Репозитарий Фаулера(точнее даже Ерика Еванса) это часть бизнеслогики.


    ВВ>>Вообще-то это совсем не так. Эванс как раз настаивает на выделении Домен Модели от всего остального (в т.ч. числе и от "инфраструктуры" или "репозитория") именно как центрального слоя бизнес-логики.


    MC>Вообще-то это именно так . Репозитарий это часть доменной модели. Если смотреть это с точки зрения реальных вещей, то это папка с ордерами. Ну а уже то как она реализована эта папка моделлеров не интересует. Репозитарий может обращаться к выделенному ДАЛ, а может быть постороен на ОРМ.


    Ну если мы говорим именно об Эвансе, то у него есть понятие infrastructure, который "provides generic technical capabilities that support the higher layers: message sending for the application, persistence for the domain, drawing widgets for the UI.
    Тогда как Домен responsible for representing concepts of the business, information about the business situation, and business rules.



    А объясняя, почему тут есть разделение Эванс ссылается на Фаулера

    Separating the domain layer from the infrastructure and user interface layers allows a much
    cleaner design of each layer.
    Isolated layers are much less expensive to maintain, because they
    tend to evolve at different rates and respond to different needs. The separation also helps with
    deployment in a distributed system, by allowing different layers to be placed flexibly in different
    servers or clients, in order to minimize communication overhead and improve performance


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

    MC>Посмотрите на http://dddsample.sourceforge.net/ это офциальный пример. Посмтрите где располгаються и как располагаються репозитарии. Обратите внимание что они работают с обьектами модели, если бы это был ДАЛ он бы возвращал рекорды(ДТО).


    Примерчик посмотрю.

    MC>Или саму книгу. Вы найдете там упоминания про виртуальные колекции и тому подобное. Это все не характеристики ДАЛ. И они не выносятся на другой слой.


    DDD? Посмотрел См. выше.

    MC>Хорошый список заблужений включая и это есть на http://tech.groups.yahoo.com/group/domaindrivendesign/. На него обычно ссылаються когда задают вопросы по типу можно ли ссылаться из модели на репозатарии. Но к сожалению я не могу его найти.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[25]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 22:28
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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


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


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


    MC>>>>Репозитарий Фаулера(точнее даже Ерика Еванса) это часть бизнеслогики.


    ВВ>>>Вообще-то это совсем не так. Эванс как раз настаивает на выделении Домен Модели от всего остального (в т.ч. числе и от "инфраструктуры" или "репозитория") именно как центрального слоя бизнес-логики.


    MC>>Вообще-то это именно так . Репозитарий это часть доменной модели. Если смотреть это с точки зрения реальных вещей, то это папка с ордерами. Ну а уже то как она реализована эта папка моделлеров не интересует. Репозитарий может обращаться к выделенному ДАЛ, а может быть постороен на ОРМ.


    ВВ>Ну если мы говорим именно об Эвансе, то у него есть понятие infrastructure, который "provides generic technical capabilities that support the higher layers: message sending for the application, persistence for the domain, drawing widgets for the UI.

    ВВ>Тогда как Домен responsible for representing concepts of the business, information about the business situation, and business rules.

    Все правильно. Иммено об Эвансе. И где вы тут видите противоречие тому что репозитарии это часть доменной модели?
    Конкретная реализация репозитария может основываться на инфраструктурном коде (persistence for the domain — ДАЛ). Но сам репозитарий это часть доменой модели.

    Это вобщемто логично что если мы моделируем реальные ордеры, то в той же модели должно быть и хранилище этих ордеров. Иначе если у нас не будет в модели чегото куда можно сохранить, как описать такой простой процес как:
    1) Получить ордер (в реальном мире пришел с товаром).
    2) Проверить ордер (в реальном мире мы его сверили с наличием).
    3) Сохранить ордер (в реальном мире в например в папке или сейфе).
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[24]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 22:33
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

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


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


    MC>>>Репозитарий Фаулера(точнее даже Ерика Еванса) это часть бизнеслогики.


    ВВ>>Вообще-то это совсем не так. Эванс как раз настаивает на выделении Домен Модели от всего остального (в т.ч. числе и от "инфраструктуры" или "репозитория") именно как центрального слоя бизнес-логики.


    MC>Вообще-то это именно так . Репозитарий это часть доменной модели. Если смотреть это с точки зрения реальных вещей, то это папка с ордерами. Ну а уже то как она реализована эта папка моделлеров не интересует. Репозитарий может обращаться к выделенному ДАЛ, а может быть постороен на ОРМ.


    MC>Посмотрите на http://dddsample.sourceforge.net/ это офциальный пример. Посмтрите где располгаються и как располагаються репозитарии. Обратите внимание что они работают с обьектами модели, если бы это был ДАЛ он бы возвращал рекорды(ДТО).


    MC>Или например почитайте тут — http://fragmental.tw/2007/11/29/repositories-misunderstandings/


    MC>Или саму книгу. Вы найдете там упоминания про виртуальные колекции и тому подобное. Это все не характеристики ДАЛ. И они не выносятся на другой слой.


    MC>Хорошый список заблужений включая и это есть на http://tech.groups.yahoo.com/group/domaindrivendesign/. На него обычно ссылаються когда задают вопросы по типу можно ли ссылаться из модели на репозатарии. Но к сожалению я не могу его найти.


    Вот, нашел довольно четкое определение Репозитория у Эванса:

    The REPOSITORY will delegate to the appropriate infrastructure services to get the job done. Encapsulating the
    mechanisms of storage, retrieval, and query is the most basic feature of a REPOSITORY
    implementation.


    Т.е. проще говоря это "морда" для инфстрактуры, некий ее фасад. То, что я в своих "ахтунг" примерах называл persistance model. Это не часть бизнес-логики совсем.
    А вот примерчик оттуда:

    public class DelinquentInvoiceSpecification 
    {
        // Basic DelinquentInvoiceSpecification code here
        public Set satisfyingElementsFrom(InvoiceRepository repository) {
                //Delinquency rule is defined as:
                // "grace period past as of current date"
            return repository.selectWhereGracePeriodPast(currentDate);
        }
    }
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[26]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 22:37
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    ВВ>>Ну если мы говорим именно об Эвансе, то у него есть понятие infrastructure, который "provides generic technical capabilities that support the higher layers: message sending for the application, persistence for the domain, drawing widgets for the UI.

    ВВ>>Тогда как Домен responsible for representing concepts of the business, information about the business situation, and business rules.

    MC>Все правильно. Иммено об Эвансе. И где вы тут видите противоречие тому что репозитарии это часть доменной модели?


    Ну я вот в соседнем посте еще одну цитатку привел. Репозиторий как бы фасад инфраструктуры, а доменная модель четко выделяется — причем на это в ДДД указывается неоднократно.

    MC>Конкретная реализация репозитария может основываться на инфраструктурном коде (persistence for the domain — ДАЛ). Но сам репозитарий это часть доменой модели.


    Гм, мне кажется при таком подходе это уже вопрос терминологии больше
    Для меня эта фасад инфрастуктуры. Доменная модель как бы использует его.

    MC>Это вобщемто логично что если мы моделируем реальные ордеры, то в той же модели должно быть и хранилище этих ордеров. Иначе если у нас не будет в модели чегото куда можно сохранить, как описать такой простой процес как:

    MC>1) Получить ордер (в реальном мире пришел с товаром).
    MC>2) Проверить ордер (в реальном мире мы его сверили с наличием).
    MC>3) Сохранить ордер (в реальном мире в например в папке или сейфе).

    Вот, код как раз в тему в моем соседнем посте. Отвественный за сохранение — часть Домена, да. Но это не часть репозитория. Он использует внутри себя репозиторий.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[25]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 22:52
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>Вот, нашел довольно четкое определение Репозитория у Эванса:


    ВВ>

    ВВ>The REPOSITORY will delegate to the appropriate infrastructure services to get the job done. Encapsulating the
    ВВ>mechanisms of storage, retrieval, and query is the most basic feature of a REPOSITORY
    ВВ>implementation.


    ВВ>Т.е. проще говоря это "морда" для инфстрактуры, некий ее фасад. То, что я в своих "ахтунг" примерах называл persistance model. Это не часть бизнес-логики совсем.


    Ну, не знаю. Следуя вашим словам репозитарий это дополнитильный слой между ДАЛ и бизнес логикой... реально же это такая же часть модели как и все остальное. Посмотрите примерчик который они выложили. Он реально очень многое обьясняет, например как смоделировать что в папке с ордерами может быть тока 150 ордеров.

    Вот еще из книги Еванса.

    But even so, take note of what has been lost. We are no longer thinking about concepts in our domain model. Our code will not be communicating about the business; it will be manipulating the technology of data retrieval. The REPOSITORY pattern is a simple conceptual framework to encapsulate those solutions and bring back our model focus.

    A REPOSITORY represents all objects of a certain type as a conceptual set (usually emulated). It acts like a collection, except with more elaborate querying capability.

    В этой цитате нема ничего о том где физически раположен репозитарий, этого вообще нема в книге. Но ИМХО тут вполне понятно сказано что репозитарий предназначен для моделирования, а не для сохранения.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[27]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 22:53
    Оценка:
    Давай даже так подойдем к вопросу.

    Репозиторий — фасад инфраструктуры.
    Вот в реальном приложении что ты будешь делать? Предпложим, что инфраструктура — это сохранение в БД, маппер и проч. Логично, что у тебя скорее всего будет некая отдельная библиотека, посвященная этому делу.
    А теперь главный вопрос

    Что эта библиотека должна "выставлять наружу"? Кучу разных интерфейсов, мапперы, классы для вызова процедур? Ну а как же изоляция? Об этом и Эванс, и Фаулер в один голос твердлят. Эванс:

    Concentrate all the code related to the domain model in one layer and isolate it from the user interface, application, and infrastructure code.


    Т.е. логично выставить наружу некие "фасадные интерфейсы", ведь так? И чем эти интерфейсы будут как не репозиторием?
    Продолжаем цитату:

    The domain objects, free of the responsibility of displaying themselves, storing themselves, managing application tasks, and so forth, can be focused on expressing the domain model.


    В общем у меня лично сложилось впечатление, что репозиторий — это не часть домена
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[26]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 22:55
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    MC>В этой цитате нема ничего о том где физически раположен репозитарий, этого вообще нема в книге. Но ИМХО тут вполне понятно сказано что репозитарий предназначен для моделирования, а не для сохранения.


    "Разорванная" у нас беседа получается:
    http://rsdn.ru/Forum/Message.aspx?mid=3191585&amp;only=1
    Автор: Воронков Василий
    Дата: 28.11.08


    На самом деле этот вопрос конечно не исключающий, скажем так, интерпретацию. "Практика показывает", что в действительности удобнее делать репозиторий фасадом инфраструктуры. Ведь такой фасад так или иначе нужно.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[26]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 27.11.08 22:56
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    MC>Ну, не знаю. Следуя вашим словам репозитарий это дополнитильный слой между ДАЛ и бизнес логикой...


    Кстати, Фаулер:

    A Repository mediates between the domain and data mapping layers


    http://martinfowler.com/eaaCatalog/repository.html
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[27]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 23:29
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    MC>>Это вобщемто логично что если мы моделируем реальные ордеры, то в той же модели должно быть и хранилище этих ордеров. Иначе если у нас не будет в модели чегото куда можно сохранить, как описать такой простой процес как:

    MC>>1) Получить ордер (в реальном мире пришел с товаром).
    MC>>2) Проверить ордер (в реальном мире мы его сверили с наличием).
    MC>>3) Сохранить ордер (в реальном мире в например в папке или сейфе).

    ВВ>Вот, код как раз в тему в моем соседнем посте. Отвественный за сохранение — часть Домена, да. Но это не часть репозитория. Он использует внутри себя репозиторий.


    Вы привели код спецификации (http://en.wikipedia.org/wiki/Specification_pattern), это обьект для инкапсуляции запросов или создания сущностей (хотя тот что вы привели тока для запросов). Но никак не сохранения. По ходу, и спецификация это тоже обьект модели.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[28]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 23:38
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

    ВВ>В общем у меня лично сложилось впечатление, что репозиторий — это не часть домена


    http://dddsample.sourceforge.net/characterization.html

    Domain services are expressed in terms of the ubiquitous language and the domain types, i.e. the method arguments and the return values are proper domain classes. Sometimes, only the service interface (what the service does) is part of the domain layer, but the implementation (how the service does it) is part of the application layer. This is analogous to how repository interfaces are part of the domain layer, but the Hibernate implementations are not.

    http://domaindrivendesign.org/discussion/messageboardarchive/DAOVersusRepository.html

    Yes. Typically a DAO ("data access object") is an
    object that belongs to the layer between your domain
    objects and their persistent datastore and has the
    resposibility of marshalling data between the domain
    objects and the datastore, encapsulating the domain
    objects from the implementation details of the
    datastore.

    A repository, on the other hand, is a concept that
    embodies a collection of contexts, aggregates, and/or
    domain objects.

    И много других

    http://search.live.com/results.aspx?q=DDD+Repository+is+part+of+the+domain&amp;form=QBNO
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[27]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 27.11.08 23:43
    Оценка: +1
    Здравствуйте, Воронков Василий, Вы писали:

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


    MC>>Ну, не знаю. Следуя вашим словам репозитарий это дополнитильный слой между ДАЛ и бизнес логикой...


    ВВ>Кстати, Фаулер:


    ВВ>

    ВВ>A Repository mediates between the domain and data mapping layers


    ВВ>http://martinfowler.com/eaaCatalog/repository.html


    Одно другому не мешает . Ктомуже Фолер про это пишет с технической точки зрения, а Еванс с точки зрения моделирования.

    В общем и целом я с тобой согласен. Мы не сошлись тока в том можно ли репозитарий считать бизнес логикой или нет... Но мы получаем деньги не за то что "счетаем", а за то что делаем. А делаем судя по всему очень даже похоже .
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[6]: роль ООП при работе с данными
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 28.11.08 03:17
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    MC>Так это же преимущество доменной модели. В отличии от анемичной, она вообще не завист от БД. Это более чем нормально строить отдельные доменные области для разныех областей применения промапленные на одни и теже физичиские данные. Если есть описанный рекваирмент, то вообще не проблема создать одну модель для склада (ордер и чаилдами ввиде ордер айтемс) и вторую для менеджера (товар, а к ниму ридонли прилинкованы ордер айтмс).


    MC>Более того в анемичной такая схема выходит значительно сложней.

    Не вижу никакой сложности. Не вижу зависимости от БД в анемичной модели. Что ты называешь "доменной моделью"? Как она взаимодействует с персистентным состоянием?
    MC> Я думаю вам легко будет представить себе модель в которой ордер айтемс для модели склада значительно отличаеться от ордер айтмс для менеджера.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[27]: роль ООП при работе с данными
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 28.11.08 06:40
    Оценка: 17 (3) +1 -1 :))) :)
    Здравствуйте, IB, Вы писали:

    ВВ>>Save в БД тоже во всем том же отдельном лаере.

    IB>Нет уж, ты от темы не увиливай, ты двавай за свои слова отвечай.
    IB>Куда пихать второй Save, если первый не в отдельном?
    Это он так витиевато пытается донести вот такой простой пример:
    public class Order<T>: OrderBase
     where T: OrderPersister, new
    {
      private static T MyPersister  = new T();
      public void Save()
        {
          MyPersister.Save(this);
        }
    }
    
    public class DBOrderPersister: OrderPersister
    {
      public override void Save(OrderBase order)
        {
          ...
        }
    }
    public class XMLOrderPersister: OrderPersister
    {
      public override void Save(OrderBase order)
        {
          ...
        }
    }
    ...
    var dbOrder = new Order<DBOrderPersister>();
    dbOrder.Save(); // ура! уехало в базу.
    var cmlOrder = new Order<XMLOrderPersister>();
    xmlOrder.Save(); // типа уехало в XML


    А избегает он приводить этот пример полностью по очень простой причине: получится чудовищно многословный и неудобный бред. Обрати внимание, что мы не смогли обойтись одним классом Ордера, даже шаблонным — иначе персистер ничего не сможет сохранить. И всё это только ради того, чтобы можно было писать dbOrder.Save().
    Далее, невооруженным мозгом можно понять, что у нас классы Order<T> несовместимы между собой, т.е. я не могу сделать Load из DB, а Save — в XML.

    На этот вопрос ВВ тоже уже отвечал, хоть и невнятно — он предлагает в таких случаях делать специальный OrderPersister, который умеет работать обоими путями. Мне, правда, совершенно непонятно, каким образом передать в order.Save() информацию о том, куда именно сохраняться. Но ВВ это не останавливает — он жжот, как дуговая сварка. Неважно, что это всё неудобно — главное, что ты, Ваня, тупой. Ты почему-то не догадываешься до выноса функционала из метода Order.Save, с оставлением сигнатуры на месте. Ты вот, считай, пишешь в своей статье, что лыжи и гамак для секса непригодны. А ВВ рассказывает тебе, что ежели упереться левой лыжей в опору гамака, а правую вытянуть вдоль тела, то, при определенной сноровке можно добиться секса, "практически лишенного недостатков лыжно-гамаковой модели".
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[6]: роль ООП при работе с данными
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 28.11.08 06:40
    Оценка: +1
    Здравствуйте, Mike Chaliy, Вы писали:

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

    MC>Нет, например глупо выгружать на клинет внутренние айдишники оредер айтемов (тех что от ордера)? Да и вы сами дальше говорите про таймстампы. Или у вас в "стройной" моделе будут еще и таимстампы? И вообще что это за фишка внутреннюю модель системы показывать как публичный контракт?
    Откуда взялась внутренняя модель?
    Речь идет о построении внешней модели под конкретный случай. Да, мы изобретаем специальный DTO "Ордер с айтемами" и отдаем его.
    MC>Типа для изменениня бизнеспроцеса поменть версию публичного контракта? Ндя.
    А как вы хотели? Если реальность поменялась?

    MC>Ну и казалось причем тут РЕСТ и синхронизация?

    При том, что в РЕСТ нет проблемы сверхжесткости контракта, придуманной идиотами-авторами SOAP. Контракт в REST легко расширять обратно совместимым образом.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[19]: роль ООП при работе с данными
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 28.11.08 06:57
    Оценка: 1 (1) +1 -1 :))
    Здравствуйте, IB, Вы писали:
    ВВ>>А по поводу — "полиморфизм классов" и "родовые отношения". Что конкретно непонятно?
    IB>Конкретно непонятно, что эти термины означают и что ты вообще имеешь ввиду, когда говоришь "объектно-ориентировано".
    Я короче понял, Ваня. Тут пришли два мега-гуру архитектуры. Мы оба сынки по сравнению с ними. Предлагаю оставить Майка с ВВ обсуждать правильное разграничение репозитория и модели, а также способы сохранить жирность модели путём выноса всех ссылок в отдельные сущности доменной модели.
    Мой ахтунгометр зашкалило еще 50 постов назад, поэтому я ставлю автопометку на эту тему.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[20]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 28.11.08 10:38
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

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

    S>Мой ахтунгометр зашкалило еще 50 постов назад, поэтому я ставлю автопометку на эту тему.
    +1
    У меня вообще настойчивое желание полтемы в юмор сненсти, так как на трезвую голову эту кашу разгребать у меня никаких сил нет, а так, чисто поржать... ))
    ... << RSDN@Home 1.2.0 alpha rev. 673>>
    Мы уже победили, просто это еще не так заметно...
    Re[20]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 28.11.08 10:38
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

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

    ВВ>>>А по поводу — "полиморфизм классов" и "родовые отношения". Что конкретно непонятно?
    IB>>Конкретно непонятно, что эти термины означают и что ты вообще имеешь ввиду, когда говоришь "объектно-ориентировано".
    S>Я короче понял, Ваня. Тут пришли два мега-гуру архитектуры.

    Я думал у вас запрещено переходить на личности...
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[7]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 28.11.08 10:38
    Оценка: -1
    Здравствуйте, Sinclair, Вы писали:

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


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

    MC>>Нет, например глупо выгружать на клинет внутренние айдишники оредер айтемов (тех что от ордера)? Да и вы сами дальше говорите про таймстампы. Или у вас в "стройной" моделе будут еще и таимстампы? И вообще что это за фишка внутреннюю модель системы показывать как публичный контракт?
    S>Откуда взялась внутренняя модель?
    S>Речь идет о построении внешней модели под конкретный случай. Да, мы изобретаем специальный DTO "Ордер с айтемами" и отдаем его.
    Вы говорити про переиспользование сущностей "стройной" модели для пердачи данных. Мне с этим сложно согласиться, так как сущности модели в 98% случаев отличаються от того что хотелось бы передать. "Внутрення" модель — это ваша стройная модель, и меня удивляет что вы ее все время пихаете во внешник контракт.

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

    S>А как вы хотели? Если реальность поменялась?
    Я хочу чтобы контракт менялся только тогда когда это нужно, а не тогда когда поменялась бизнес логика.

    MC>>Ну и казалось причем тут РЕСТ и синхронизация?

    S>При том, что в РЕСТ нет проблемы сверхжесткости контракта, придуманной идиотами-авторами SOAP. Контракт в REST легко расширять обратно совместимым образом.
    Судя по всему "мега-архитект" не вкурсе что в SOAP нет ни слова про сверхжесткость контракта данных. SOAP вообще глубоко ложить на то что вы передадите в боди. Даже вебсервисы асп.нет потдерживают этот режим... По ходу, все тоже самое справедливо и для РЕСТ... И никак оно проблемы сложных ДТО не решает.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[21]: роль ООП при работе с данными
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 28.11.08 11:52
    Оценка: :)
    Здравствуйте, Mike Chaliy, Вы писали:
    MC>Я думал у вас запрещено переходить на личности...

    Ну, я надеюсь, что по старому знакомству Иван меня простит за "сынка".
    Но если чего — юлить и ломаться не буду, честно выдержу наложенный бан.
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Re[28]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 28.11.08 12:41
    Оценка: -1 :)
    Здравствуйте, Sinclair, Вы писали:

    ВВ>>>Save в БД тоже во всем том же отдельном лаере.

    IB>>Нет уж, ты от темы не увиливай, ты двавай за свои слова отвечай.
    IB>>Куда пихать второй Save, если первый не в отдельном?
    S>Это он так витиевато пытается донести вот такой простой пример:

    Я вам "так витиевато" пытаютсь донести то, что вообще-то предлагается в той самой концепции, которую вы критикуете. Но судя по реакции — это для вас в новинку
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[21]: роль ООП при работе с данными
    От: AndrewJD США  
    Дата: 28.11.08 13:09
    Оценка:
    Здравствуйте, IB, Вы писали:

    S>>Мой ахтунгометр зашкалило еще 50 постов назад, поэтому я ставлю автопометку на эту тему.

    IB> +1
    IB>У меня вообще настойчивое желание полтемы в юмор сненсти, так как на трезвую голову эту кашу разгребать у меня никаких сил нет, а так, чисто поржать... ))

    Да ладно вам, поржать... Когда приходится разгребать все прелести жирного ООП в реальном проекте — совсем несмешно.
    "For every complex problem, there is a solution that is simple, neat,
    and wrong."
    Re[2]: причины
    От: Аноним  
    Дата: 28.11.08 16:29
    Оценка:
    Есть свой Framework для разработки приложений для конкретной предметной области.
    С достаточно удобной объектной моделью. (MVC, Tools, Commands, Document, Views, Panels, фабрика GUI и т. п.)

    Для работы с БД используем ORM.

    Для передачи данных WebServices. Они поверх Windows-Service'ов. Кое что написано с использованием C/C++.

    Использовали ClickOnce для обновления — збили, написали своё.
    Re[3]: причины
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 28.11.08 18:00
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>Есть свой Framework для разработки приложений для конкретной предметной области.

    А>С достаточно удобной объектной моделью. (MVC, Tools, Commands, Document, Views, Panels, фабрика GUI и т. п.)

    А>Для работы с БД используем ORM.


    А>Для передачи данных WebServices. Они поверх Windows-Service'ов. Кое что написано с использованием C/C++.


    А>Использовали ClickOnce для обновления — збили, написали своё.


    Ваша компания не Microsoft называется?

    Обычно дороговато выходит создание своих велосипедо в таком количестве.
    Общество обиженых анемистов
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 28.11.08 20:50
    Оценка: -1 :))
    Здравствуйте, AndrewJD, Вы писали:

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


    S>>>Мой ахтунгометр зашкалило еще 50 постов назад, поэтому я ставлю автопометку на эту тему.

    IB>> +1
    IB>>У меня вообще настойчивое желание полтемы в юмор сненсти, так как на трезвую голову эту кашу разгребать у меня никаких сил нет, а так, чисто поржать... ))

    AJD>Да ладно вам, поржать... Когда приходится разгребать все прелести жирного ООП в реальном проекте — совсем несмешно.


    "Общество обиженых анемистов"

    УСТАВ

    1. Общие положения


    • 1.1. "Общество обиженых анемистов" является общественной организацией (некоммерческой общественной организацией), включающей в себя на принципах добровольного участия сторонников анемичных моделей.
    • 1.2. Общество обладает собственным уникальным мнением как надо писать програмы.
    • 1.3. Общество являеться прямым конкурентом компании 1С, с ее програмным обеспечением 1С Предприятие 8.0.
    • 1.4. Общество руководствуется своим пониманием принципов програмирования. В случае отсутвия общепризнаных принципов, общество обязуеться приитянуть что нибуть за уши.


    2. Цели, задачи и методы Общества


    • 2.1. Основной целью Общества является защита анемичной модели от поясгательств других моделей.
    • 2.2. Разработка и внедрение программ, формирующих анемичное мировоззрение;
    • 2.3. Для осуществления вышеперечисленных задач Общество планирует применять следующие методы:
    — сбор информации про недостатки в других моделях;
    — организацию подрывной деятельности в других моделях;
    — повсемесном продвижении ДатаСетов как идеальной анемичной модели;
    — распространиение информации про потерянные годы работы с дургими моделями;
    — публичное сжигание книг по архитектурам корпоративных приложений;

    3. Права Общества


    • 3.1. Общество имеет четкую неопределенную структуру, в кторой найдеться место любому пострадавшему от ига других моделей.
    • 3.2. Общество вправе заниматься распространиением ДатаСетов.
    • 3.3. Члены общества не имеют права использвать методы в своих сущностях.
    • 3.3. Члены общества должны принимать что наличие атрибутов в классе уже достаточная отвественность. Наличие мтодов тоже.


    4. Членство в Обществе


    • 4.1. Членом Общества может стать любое лицо, достигшее 18 лет, принимающее его Устав, в той или иной форме обиженное представителями других моделей.
    • 4.2. Заявки от индусов с прямолинейным анемичным мышлением рассматриваються в первую очередь.


    5. Контроль за деятельностью Общества


    • 5.1. Контроль за членами возлагаеться под неусыпное бдение руководства. Основным предметом контроля являються методы в сущностях модели.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[21]: роль ООП при работе с данными
    От: Воронков Василий Россия  
    Дата: 28.11.08 23:30
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    MC>Я думал у вас запрещено переходить на личности...


    А ты сам бы смог доказать преимущества анемичной модели без перехода на личности?
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    Re[22]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 28.11.08 23:55
    Оценка:
    Здравствуйте, Воронков Василий, Вы писали:

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


    MC>>Я думал у вас запрещено переходить на личности...


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


    Все кроме "не будем показывать пальцом" понимают, что во всех моделях есть плюсы и минусы. Все зависит тока от разработчка. Если есть два разработчика с приблизительно равным експириенсом, но в разных моделях, то никто друг друга не переубедит, это просто не реально. Обе модели решают одни и теже задачи, и обе с этим справляються.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[4]: причины
    От: Аноним  
    Дата: 29.11.08 10:51
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Ваша компания не Microsoft называется?


    G>Обычно дороговато выходит создание своих велосипедо в таком количестве.


    Нет. Не Microsoft. Просто существующие наработки, не важно кого,
    нам не подходят — слишком специфична предметная область.

    Поначалу дороговато, потом на конвейер поставлено всё в виде плагинов.
    Клепаем один за одним. Не боимся за то, что столкнёмся с трудностями и
    всё лаконично и гармончно выходит.

    Вот так вот
    Re[5]: причины
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 29.11.08 18:38
    Оценка:
    Здравствуйте, Аноним, Вы писали:

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


    G>>Ваша компания не Microsoft называется?


    G>>Обычно дороговато выходит создание своих велосипедо в таком количестве.


    А>Нет. Не Microsoft. Просто существующие наработки, не важно кого,

    А>нам не подходят — слишком специфична предметная область.
    И что за предметная область? И что за проект вообще?

    А>Поначалу дороговато, потом на конвейер поставлено всё в виде плагинов.

    А>Клепаем один за одним. Не боимся за то, что столкнёмся с трудностями и
    А>всё лаконично и гармончно выходит.
    Все равно сомневаюсь что написание такого количества велосипедов оправдано.

    А>Вот так вот
    Re: роль ООП при работе с данными
    От: Аноним  
    Дата: 29.11.08 18:54
    Оценка: 1 (1) -1
    я вот читаю и думаю, — этот разговор имеет смысл. и прикол в том, что длится он так долго не потому что кто-то искренне заблуждается, а кто-то точно знает как нужно, а потому, что нет не то что четких количественных характеристик, а нет даже четкого определения, и если в крайних случаях еще можно говорить что-где, то в граничных аж никак, из-за этого и множество интерпретаций. как на мой взгляд, разговор сводится что-то в духе: это более объектно, а это менее объектно, да нет вы просто фишку не рубите, и не правильно понимаете отцов OOП — они имели в виду вот так, а значит это самый из самых ООП подходов — просто вы забыли об этом подходе и новая трактовка, новой трактовки.

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

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

    к чему я это все пишу — к тому что тема интересная — и реально достойна для обсуждения... но обсуждение может преследовать разные цели — если просто поболтать — тогда тема удалась, а если результатом должно быть понимание, обучение и.д. для того чтобы убедиться, для себя же родного, в своей правоте или, возможно, поменять свое мнение и использовать что-то лучше чем использовал до этого, или обосновать подход перед начальством, или просто получить знания, то разговор должен быть предметным, обоснованным какими-то с "объективными, измеримыми" критериями и тогда действительно можно кого-то переубедить или доказать свою правоту вы не находите ?
    Re[2]: роль ООП при работе с данными
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 29.11.08 20:32
    Оценка:
    Здравствуйте, Аноним, Вы писали:



    А>я вот читаю и думаю, — этот разговор имеет смысл. и прикол в том, что длится он так долго не потому что кто-то искренне заблуждается, а кто-то точно знает как нужно, а потому, что нет не то что четких количественных характеристик, а нет даже четкого определения, и если в крайних случаях еще можно говорить что-где, то в граничных аж никак, из-за этого и множество интерпретаций. как на мой взгляд, разговор сводится что-то в духе: это более объектно, а это менее объектно, да нет вы просто фишку не рубите, и не правильно понимаете отцов OOП — они имели в виду вот так, а значит это самый из самых ООП подходов — просто вы забыли об этом подходе и новая трактовка, новой трактовки.


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


    А>я понимаю что проблема сложная и что нет четких характеристик, но все же .... есть методики преобразования количественных характеристик в качественные, есть же возможность определить что значит «хороший» или «плохой». правда "хорошим" он будет для одной категории а менее хорошим или более для другой, но в нашем случае это уже результат.


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


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


    ИМХО если бы можно было объективно построить хотябы отношение порядка (даже не количественную метрику) между используемым подходами, то таких тем как эта не возникало бы.
    Re[3]: роль ООП при работе с данными
    От: Aikin Беларусь kavaleu.ru
    Дата: 01.12.08 08:03
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Так в том и дело, что адекватных метрик для оценки архитектурного решения не существует.

    G>Есть куча первичных метрик, типа количество строк, связность классов, и прочее. Эти метрики зависят от размеров проекта и учитывать их бессмысленно.
    G>Также есть некоторое количество производных метрик, которые хоть и не зависят от размера проекта, но практически не могут показать хорошесть какого-либо архитектурного решения.
    +1

    G>ИМХО если бы можно было объективно построить хотябы отношение порядка (даже не количественную метрику) между используемым подходами, то таких тем как эта не возникало бы.

    И можно было бы посадить мартышек-архитекторов за тулзу генерящую архитектуру системы на основе этого отношения порядка (ну, или, нескольких альтернативных вариантов архитектуры).
    Re[21]: роль ООП при работе с данными
    От: Безон Великобритания  
    Дата: 09.12.08 21:06
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    B>Тут что я ещё хочу отметить. Бизнес логика в подавляющем большинстве случаев не является поведением бизнес сущностей. А является процессом, который эти сущности использует. Поэтому всё что ты пишешь правильно, но для случаев, когда сущность, действительно, обладает каким-то поведением. Но во многих примерах поведение приписывается сущности ошибочно. Например, заказ, это всего лишь бумажка с данными. У него нет поведения. И операция "оформить заказ" это поведение оформителя заказов, а не заказа. В свою очередь "оформитель заказов" — сущность, зачастую, напрочь лишенная данных.


    Могу лишь уточнить что группировать поведение можно как вокруг объекта действия так и вокруг субъекта. Это становится возможным потому что объекты взаимодействуют, а не просто действуют.
    -----
    Re[22]: роль ООП при работе с данными
    От: Blazkowicz Россия  
    Дата: 10.12.08 10:00
    Оценка: 1 (1)
    Здравствуйте, Безон, Вы писали:

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

    О том и речь, что если "формировать" все методы действия над "субъектом" в классе субъекта, то что же из этого выйдет. А выйдет каша.
    Re[9]: роль ООП при работе с данными
    От: Sergey T. Украина http://overstore.codeplex.com
    Дата: 06.01.09 13:44
    Оценка: 8 (1) +1
    Здравствуйте, Sinclair, Вы писали:

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


    M>>В моей реальности тоже алгоритм и его изменения первичны. Но у меня есть шеф. ТЧК. Его эти алгоритмы не интересуют, или точнее стоят на втором месте.

    S>Вы просто плохо понимаете, о чем вам толкует шеф.
    .....


    Целиком и полностью согласен с г-м Sinclair

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

    Так вот. Для задачи ввода данных очень хорошо подходит объектная модель, более того, богатая объектная модель. Почему? Потому что при вводе данных очень много обработки локального набора данных, в терминах ООП — объекта. Это валидация, пересчет полей, и т.п.
    (Кстати, совсем не обязательно хранить алгоритмы обработки внутренних данных в объекте, можно лишь вызывать их оттуда. Но это так, камень в огород противников Rich Model, которые считают скидки в строке заказа.) Здесь на помощь приходит типизированность, инкапсуляция, средства структурирования кода и т.п. Самое главное, что в задаче ввода данных объектная модель очень помогает своей структурированностью (кроме специфических случаев не- или слабоструктурированных данных). Если использовать для ввода данных, к примеру, нетипизированные датасеты, то мы теряем контроль типов, кроме того, логику, локальную для единичных объектов нам помещать опять же некуда (хотя тут спасут датасеты типизированные). Но в любом случае, это все будет выглядеть неестественно и странно, и датасетная природа съест мозг в самом скором времени, особенно, когда кто-нибудь поддастся соблазну ввести зависимости поведения от состояния Новый-Изменен-Удален и т.п. Использование других контейнеров, например, ХМЛ файлов, связано с аналогичными проблемами. Особенно весело становится при необходимости предоставления АПИ во внешний мир.

    Задача же показа данных (reporting) уже стоит совсем по-другому. Здесь на первом месте стоит скорость, а на втором гибкость. Обработка данных здесь по большей части массовая. Здесь объекты ни к чему. Потому что логика, которая содержится в объектах, их поведение здесь по большей части бесполезна. Использование объектов здесь даже противопоказано, потому что вносит ненужный оверхеад на преобразование массива данных в массив объектов, а значит страдает скорость, а во-вторых, вынуждает считаться со структурой самих объектов и не позволяет малыми усилиями отойти от нее, а значит, страдает гибкость.
    There is no such thing as the perfect design.
    Re[6]: роль ООП при работе с данными
    От: Sergey T. Украина http://overstore.codeplex.com
    Дата: 18.02.09 16:51
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

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

    MC>Нет, например глупо выгружать на клинет внутренние айдишники оредер айтемов (тех что от ордера)? Да и вы сами дальше говорите про таймстампы. Или у вас в "стройной" моделе будут еще и таимстампы? И вообще что это за фишка внутреннюю модель системы показывать как публичный контракт? Типа для изменениня бизнеспроцеса поменть версию публичного контракта? Ндя.

    Почему глупо выгружать айди? Почему глупо выгружать таймстампы? И самый главный вопрос: причем тут стройная модель? Выгрузка идентификаторов — это способ обеспечения идентификации экземпляра объекта. Потому что, например, в .НЕТ реализации распределенных приложений (за исключением, пожалуй, ремоутинга) нет другого стандартного способа идентификации экземпляров, кроме идентификации по данным, причем эту идентификацию нужно реализовывать самому (перекрывать Equals). С таймстампами немного другое, передача таймстампов — это способ, необходимый для реализации сервиса без состояния. Т.к. таймстампы все-равно нужны, и есть всего два места, где их хранить — либо на сервере, либо передавать туда-сюда на клиента.

    Кстати, почему бы внутреннюю модель не показывать как публичный контракт?

    Кстати, все написанное мной выше писалось в расчете на то, что таймстампы все-таки нужны.
    MC>Насколько я понял (я не нашел гдето упоминания слова "синхронизация") вы сами придумали необходимость таймстампов?
    MC>Иначе говоря над жирными моделями всегда есть фасады. А фасады возвращают ДТО. Будет ли это ремот фасад или просто сервис лэер роли не играет. У нас уже есть ДТО с достаточным уровнем деталиации. Никуда вобщемто жирная модель не пролитает.
    Это верно только если вы не против сервисов с состоянием. Тогда для любого объекта можно создать ДТО с уровнем детализации, необходимым для решения задачи. Однако, если сервисы с состоянием не устраивают, то в ДТО помимо бизнес данных приходится складывать еще и данные, необходимые для восстановления состояния объекта модели
    There is no such thing as the perfect design.
    Re[7]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 18.02.09 17:42
    Оценка:
    Здравствуйте, Sergey T., Вы писали:

    Сложно о чем то спорить если вы читать не умеете....
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[8]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 19.02.09 11:10
    Оценка: 1 (1)
    Здравствуйте, Mike Chaliy, Вы писали:

    MC> Мне с этим сложно согласиться, так как сущности модели в 98% случаев отличаються от того что хотелось бы передать.

    Если сущности на 98% отличаются от того, что хочется передать, значит они на 98% не правильно спроектированы.

    MC>Я хочу чтобы контракт менялся только тогда когда это нужно, а не тогда когда поменялась бизнес логика.

    Контракт никак не зависит от бизнес-логики, так как в стройной модели никакой бизнес-логики не содержится.

    MC>Судя по всему "мега-архитект" не вкурсе что в SOAP нет ни слова про сверхжесткость контракта данных.

    Дело не в словах, а в том как это на самом деле работает. В SOAP ты должен явно и жестко прописать контракт и строго ему следовать. Малейшее изменение контракта порождает новую версию сервиса. Именно об этом и говорил Синклер, когда присал про сверхжесткость. Изменение однажды созданного DTO порождает новую версию сервиса, при том, что старые клиенты никуда не деваются и при самом печальном раскладе, необходимо поддерживать все когда-либо созданные версии DTO и сервисов — в этом собственно и есть основная проблема SOAP, которую призван решить REST.

    MC>SOAP вообще глубоко ложить на то что вы передадите в боди. Даже вебсервисы асп.нет потдерживают этот режим...

    Проблема, что только они этот режим и поддерживают.

    MC> По ходу, все тоже самое справедливо и для РЕСТ... И никак оно проблемы сложных ДТО не решает.

    Ключевое отличие REST в том, что в нем DTO фактически генерится на лету, во время построения запроса. Неким подобием контракта ограничины только базовые сущности, по которым строится запрос. Именно это и решает "прблемы сложных DTO" и объясняет популярность REST.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
    Мы уже победили, просто это еще не так заметно...
    Re[9]: роль ООП при работе с данными
    От: Mike Chaliy Украина http://chaliy.name
    Дата: 19.02.09 11:41
    Оценка:
    Здравствуйте, IB, Вы писали:

    По ходу, вы там собирались игонрить эту тему... Забыли?

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


    MC>> Мне с этим сложно согласиться, так как сущности модели в 98% случаев отличаються от того что хотелось бы передать.

    IB>Если сущности на 98% отличаются от того, что хочется передать, значит они на 98% не правильно спроектированы.
    Это из категории "ляпнул и не обосновываеш".

    В одном из моих проектов несколько фронтендов к доменной логике. На примере кастомера, для УИ фронтедна у меня у кастомера около 40ка полней, для веб-сервиса около 10ти. Я не вижу необходимости пердавать остальные трдицать тока ради того что "не правильно спроектированы"... Пойми же в рич модели никто не тычит эти обьекты куда попадя и куда не попадя, как в "стройной". В рич моделях всегда еться фасады кторые отдают тока то что надо и не одной пропертей больше.

    MC>>Я хочу чтобы контракт менялся только тогда когда это нужно, а не тогда когда поменялась бизнес логика.

    IB>Контракт никак не зависит от бизнес-логики, так как в стройной модели никакой бизнес-логики не содержится.


    MC>>Судя по всему "мега-архитект" не вкурсе что в SOAP нет ни слова про сверхжесткость контракта данных.

    IB>Дело не в словах, а в том как это на самом деле работает. В SOAP ты должен явно и жестко прописать контракт и строго ему следовать. Малейшее изменение контракта порождает новую версию сервиса. Именно об этом и говорил Синклер, когда присал про сверхжесткость. Изменение однажды созданного DTO порождает новую версию сервиса, при том, что старые клиенты никуда не деваются и при самом печальном раскладе, необходимо поддерживать все когда-либо созданные версии DTO и сервисов — в этом собственно и есть основная проблема SOAP, которую призван решить REST.
    1) В SOAP я ниего не должен. В теории контракт можно ограничить WDSL (и XSD). Это теория. SOAP можно использовать и с ad-hoc XML. Более того громадное количество спек на этом свободно основываеться (пример WS-Management).
    2) Если у меня не изменяет память то у Синклера всегда было свое виденье на веб-сервисы, которое основываеться на том что может фреймворк который он использует... А мож и не у Синклера... Не суть.
    3) Версия добовляеться тока в случае "ломающих" изменений. Добовления парметра, аргумента не требуют добовления новой версии.
    4) В REST все тожде самое. Точно также как и в SOAP у него тем или иным способом описывают схему. Пока что в REST нет стандарта на это но все к тому идет. Можеш поискать, это легко находиться. Без схемы в том или ином виде ты не сможеш консьюмить не тот, не тот сервис.
    5) Единственное существенное отличие между SOAP и REST это семантика. В SOAP сообщения, в REST изменение состояния. Все. Решения твоей "проблемы" у REST даже в мыслях небыло....

    MC>>SOAP вообще глубоко ложить на то что вы передадите в боди. Даже вебсервисы асп.нет потдерживают этот режим...

    IB>Проблема, что только они этот режим и поддерживают.
    гм, они оба режима подтдерживают... в чем проблема?

    MC>> По ходу, все тоже самое справедливо и для РЕСТ... И никак оно проблемы сложных ДТО не решает.

    IB>Ключевое отличие REST в том, что в нем DTO фактически генерится на лету, во время построения запроса. Неким подобием контракта ограничины только базовые сущности, по которым строится запрос. Именно это и решает "прблемы сложных DTO" и объясняет популярность REST.
    Ыыыыыы, вы это откуда взяли? Мож стоит почитать про него? Ну хотябы немного? Теорию. Даже википедии достаточно.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
    А тут я живу и пишу...
    Re[10]: роль ООП при работе с данными
    От: IB Австрия http://rsdn.ru
    Дата: 19.02.09 19:43
    Оценка:
    Здравствуйте, Mike Chaliy, Вы писали:

    MC>Это из категории "ляпнул и не обосновываеш".

    Ну так ты тем же самым занимаешься, какой вопрос — такой и ответ.

    MC> На примере кастомера, для УИ фронтедна у меня у кастомера около 40ка полней, для веб-сервиса около 10ти.

    А внутри ты у себя все 40, во всех сценариях используешь? Ага.

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

    Ну тут уж сам решай.. =)

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

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

    MC>1) В SOAP я ниего не должен. В теории контракт можно ограничить WDSL (и XSD). Это теория.

    Это практика. В SOAP клиент не может сказать серверу — верни мне кастомеров с 3-го по 8-й, за вчерашний день, если разработчик на сервере не предусмотрел соответствующего метода. Были, конечно попытки это дело обойти, expressin-tree сериализуя, например, но чтобы что-то из этого увенчалось успехом, я не слышал.

    MC>2) Если у меня не изменяет память то у Синклера всегда было свое виденье на веб-сервисы, которое основываеться на том что может фреймворк который он использует... А мож и не у Синклера... Не суть.

    Сильный аргумент =) Так суть или не суть? Дело в том, что Синклер столкнулся с этим именно на практике, так как у него может быть произвольный фреймворк на противоположной стороне и куча разношерстных клиентов со своими хотелками — как раз тот сценарий, ради которого SOAP и задумывался. Так что я бы на твоем месте его бы послушал, вместо википедии..

    MC>3) Версия добовляеться тока в случае "ломающих" изменений. Добовления парметра, аргумента не требуют добовления новой версии.

    Хрен редьки не слаще, да и не про добавление параметра речь.

    MC>4) В REST все тожде самое. Точно также как и в SOAP у него тем или иным способом описывают схему.

    MC> Пока что в REST нет стандарта на это но все к тому идет. Можеш поискать, это легко находиться. Без схемы в том или ином виде ты не сможеш консьюмить не тот, не тот сервис.
    Не тоже и не ту схему там описывают. В конечном итоге, в REST клиент определяет что именно он получит, а в SOAP это все жестко прошито на сервере.

    MC>5) Единственное существенное отличие между SOAP и REST это семантика.

    Семантика чего? =)

    MC>гм, они оба режима подтдерживают... в чем проблема?

    Проблема в том, что далеко не все реализации SOAP так умеют. Сценарий когда на обоих сторонах один и тот же фреймворк — мало интересен, там хоть голые данные гоняй, как-нибудь договорятся.

    MC>Ыыыыыы, вы это откуда взяли? Мож стоит почитать про него? Ну хотябы немного? Теорию. Даже википедии достаточно.

    Да, стоит — почитай.
    ... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
    Мы уже победили, просто это еще не так заметно...
    Re[7]: роль ООП при работе с данными
    От: Ziaw Россия  
    Дата: 20.02.09 04:23
    Оценка:
    Здравствуйте, Sinclair, Вы писали:

    S>Речь идет о построении внешней модели под конкретный случай. Да, мы изобретаем специальный DTO "Ордер с айтемами" и отдаем его.

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

    S>При том, что в РЕСТ нет проблемы сверхжесткости контракта, придуманной идиотами-авторами SOAP. Контракт в REST легко расширять обратно совместимым образом.


    А можно какие-то ссылки описывающие контракт РЕСТ? Все, что я читал по этом поводу не наводило меня на мысли о какой-то спецификации контракта. У меня сложилось впечатление, что РЕСТ это способ построения архитектуры на контрактах сервера в стиле CRUD (точнее GPPD, но эту аббревиатуру я не встречал). Правда я уже давно не слежу за его развитием, поскольку идеи впечатляют, а реализации не очень, так что буду благодарен за любую инфу. Было бы совсем здорово статью на РСДН (мечтать).
    ... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
    Re[8]: роль ООП при работе с данными
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 20.02.09 09:18
    Оценка:
    Здравствуйте, Ziaw, Вы писали:
    Z>А можно какие-то ссылки описывающие контракт РЕСТ?

    Ну, вообще описывать контракт в REST не обязательно — он, типа, такой self-descriptive, что контракт как бы и не нужен.
    Всё, что нужно знать — это адрес точки входа. Все остальные "места" в REST-пространстве должны быть достижимы по ссылкам из входной точки (connectedness), а их смысл легко будет понятен человеку, который по ним кликает. То есть специальных усилия для обеспечения discoverability не нужно.

    Но на практике нам важно два фактора:
    1. Анализ документа. В простейших случаях документ используется как монолит: к примеру, это картинка, которую мы показываем пользователю as is.
    В остальных случаях нужно из полученного документа что-то извлекать. Как правило, документ — это некий XML. XML позволяет авторам сервиса легко расширять структуру, но вот для сохранения совместимости нужно как-то объяснить потребителям правильный способ доставания данных.
    Ну, чтобы парни не имели искушения вытаскивать ссылку на EULA как "четырнацатый link в документе", что сломается при малейшем изменении схемы.
    Поэтому контракт на структуру документа можно описать в виде набора XPath-выражений, которые обязуются вернуть определенные данные.

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

    Но заставлять его делать это каждый раз — не всегда эффективно; поэтому иногда автор сервиса еще и публикует схему адресации документов.
    И тогда потребитель может сразу запросить /sibir/tomsk/prices/2009/02/21.xhtml. Но тогда автору сервиса придется гарантировать целостность этих ссылок; и если что-то поменяется, придется держать настроенные редиректы в течение длительного срока.

    Z>Все, что я читал по этом поводу не наводило меня на мысли о какой-то спецификации контракта. У меня сложилось впечатление, что РЕСТ это способ построения архитектуры на контрактах сервера в стиле CRUD (точнее GPPD, но эту аббревиатуру я не встречал).

    Совершенно верно. REST — это способ построения архитектуры. Но у этих архитектур есть типичные черты. Посмотри на http://code.google.com/apis/gdata/ — там приведены контракты на рестовские интерфейсы гугла.
    Вот, собственно, основа:
    http://code.google.com/apis/gdata/docs/2.0/reference.html
    Обрати внимание, что приведена спецификация устройства URL, а также спецификация на структуру возвращаемого документа.

    Правда я уже давно не слежу за его развитием, поскольку идеи впечатляют, а реализации не очень, так что буду благодарен за любую инфу. Было бы совсем здорово статью на РСДН (мечтать).
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.