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>>
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.