Re: Структура классов модели предметной области
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 14.01.08 22:26
Оценка: 2 (2) +1
Здравствуйте, Аноним, Вы писали:

А>Посоветуйте, пожалуйста, как лучше и правильнее.

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

  1. За что (за выполнение каких обязанностей) отвечает класс Customer?
  2. За что (за выполнение каких обязанностей) отвечает класс Order?
  3. За что (за выполнение каких обязанностей) отвечает класс OrderLine?


А>Есть класс заказа — Order. У заказа есть клиент, т.е. Customer. Так вот в классе Order хранить ли объект типа Customer? Или хранить CustomerID? Подозреваю, что правильнее первый вариант.

Почему правильнее хранить Customer'а? Совсем необязательно. В классе Order вполне достаточно хранить только CustomerID. И подгружать Customer'ов по мере необходимости. А чтобы не подгружать тех Customer'ов, которые уже когда-о были подгружены, можете завести класс Диспетчер Customer'ов, в котором организовать кэш. Как только Вам потребуется реальный Customer, Вы сразу же обращаетесь к Диспетчеру Customer'ов и передаёте ему CustomerID. А он либо подгружает его из БД, либо берёт из кэша.

Точно такой же механизм можете организовать и для заказов, введя Диспетчер Заказов.

А>Второй вопрос по задаче Order и OrderLine. Хранить ли IList<OrderLine> OrderLines в классе Order или нет? Если да, то как правильнее организовать работу? Когда загружать? А если в заказе 1000 позиций? А может они нам не понадобятся?

Тут Вам надо побеседовать с Клиентом и узнать, какое максимальное количество позиций может содержать Заказ? А также — процент таких заказов от общего числа заказов.

Если заказы размером в 100 или 1000 позиций встречаются часто, то, конечно, не стоит подгружать все позиции. Если таких заказов очень мало, и основной процент заказов содержит 3 — 5 позиций, то, думаю, можно подгрузить все позиции при загрузке заказа.

Если решите не подгружать все позиции сразу, то рекомендую Вам поступить точно так же, как и с Customer'ами — завести Диспетчер Позиций Заказа. Сам Заказ может содержать идентификаторы позиций. А вот если нужны будут данные конкретной позиции, то следует обратиться к Диспетчеру Позиций Заказа.
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 15.01.08 23:14
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>Есть класс заказа — Order. У заказа есть клиент, т.е. Customer. Так вот в классе Order хранить ли объект типа Customer? Или хранить CustomerID?

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

А>Подозреваю, что правильнее первый вариант. Но второй вариант проще, иногда удобнее и быстрее. Например, из веб-сервиса нам может прийти объекта заказа с полем CustomerID т.к. веб-сервис не знает о типе Customer, и получается нам чтобы создать объект заказа типа Order нужно будет по CustomerID получать объект типа Customer (это будет занимать время, а потом информация о клиенте может и не понадобится). Как правильно?

Тут как извечный выбор гармонии между памятью и производительностью. Выгребая всегда сущности вместе мы тратим излишнюю память, что на больших структурах в системах обслуживающих много пользователей критично. Выгребая сущности по отдельности мы теряем в производительности, так как используюется как минимум один запрос на каждый объект, вместо, например выборки нескольких объектов одним запросом через join.
В случае с Hibernate используется такая стратегия что все объекты по-умолчанию подгружаются отдельно. Тем самым использование памяти сводится к минимуму.
А потом уже в более зрелом приложении находятся участки, которые можно подвергнуть оптимизации и для них в методах DAO указывается что такие-то ассоциации нужно подгружать сразу.


А>Допустим, что все-таки правильнее хранить в классе Order объект типа Customer, а не CustomerID, тогда как загружать заказ из БД? Одним запросом с джоином из таблицы клиентов или отдельно загрузить данные только из таблицы заказов а потом отдельным запросом типа

А>
order.Customer = CustomerRepository.GetCustomer(customerID);

А>?
Тут не понятно откуда берется customerID, если он у нас не в order.
В Hibernate сделано так что при загрузки order вместо Customer подставляется прокся. И при первом же обращении к Customer прокся загружает данные.
В тоже время если мы хотим оба объекта одним запросом мы можем это сделать просто указав что ассоциация должна быть загружена сразу.

А>Второй вопрос по задаче Order и OrderLine. Хранить ли IList<OrderLine> OrderLines в классе Order или нет? Если да, то как правильнее организовать работу? Когда загружать? А если в заказе 1000 позиций? А может они нам не понадобятся?

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

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

Вопросы, к слову, совсем не глупые.
Re[42]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 25.01.08 13:04
Оценка: +2
IB, буду (а возможно и не только я) вам очень благодарен если уделите немного времени и приведете пример работы, например с таблицами customer, order, orderlines. Заказ включает в себя клиента и строки заказа (если бы вы сделали по другому — напишите как). Как бы выглядели в вашем случае классы, как бы вы заполняли объекты если например нужно отобразить все заказы и их позиции? Как бы вы все это загрузили в грид? Приведите пожалуйста примеры кода.
Re[2]: Структура классов модели предметной области
От: KolanT  
Дата: 15.01.08 05:59
Оценка: 1 (1)

Customer. Так вот в классе Order хранить ли объект типа Customer?

нет, не надо так делать.

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

Как раз таки правильно хранить ID. Такое отношение называется спецификацией(точное название искать в книге Лармана).

В реальной же предм. область Заказ — это бумажка, а Клиент — это не просто человек с фамилией именем отчеством, а еще и с прической, полом, характером, лысиной.. Так как же вы этого несчастного человека засунете в бланк с Заказом?
В Заказе содержится ссылка на Клиента(код например) а не ои сам.

Если вы засунете Клиента в Заказ, то тут же получите дублирование данных, ведь может быть несколько заказов у 1 клиента. Допустим у вас есть заказы 1 и 2 и клиент Вася, который их выставил.

При хранении клиента в заказе получится:
1 — Вася
2 — Вася

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


Итого:
Заказ должен хранить ссылку(код) на Клиента.
Re: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 15.01.08 08:10
Оценка: +1
Здравствуйте, Аноним, Вы писали:

В БД — Customer конечно хранится отдельно. Что касается классов — то тут посмотри на формы. Обращай внимание — какая информация нужна от Customer. Как часто используется. Список или один счет. Для одного счета можно и отдельно подгрузить. Или, он вообще не нужен. Или очень часто запрашиваются счета для определенного Customer. Иногда, при отображении списка заказов важно только его имя. Тогда можно сделать дополнительное readonly свойство — CustomerName.
Re[3]: Структура классов модели предметной области
От: Trean Беларусь http://axamit.com/
Дата: 15.01.08 14:04
Оценка: +1
Здравствуйте, KolanT, Вы писали:

KT>

KT>Customer. Так вот в классе Order хранить ли объект типа Customer?

KT>нет, не надо так делать.

Речь как я понимаю ведется о том, чтобы хранить объектную ссылку на объект в другом объекте или хранить pk этого объекта. Лучше конечно, ссылку, так правильнее с точки зрения ОО дизайна, так как в этом случае нет привязки к тому, как хранятся и идентифицируются объекты в хранилище (это не обязательно РСУБД и PK).
Re: Структура классов модели предметной области
От: ArchitectNewbie  
Дата: 16.01.08 02:43
Оценка: -1
Я вот подумал, может быть надо меньше размышлять, а больше подходить с практической точки зрения, т.е. просто смотреть а насколько реально падает скорость работы если сразу подгружать другие объекты предметной области, т.е. если в класс Order сразу загружать Customer'а или в класс Customer сразу загружать IList<Order> CustomerOrders и т.д. Если было 2 мс, а стало 3 мс, то наверное и не надо заморачиваться и просто грузить все сразу. Еще можно подходить с точки зрения одного запроса — т.е. если 1 запросом (join'ом) можно загрузить доп. объект, то так и делать (опять же если производительность не пострадает).

По поводу Customer или CustomerID я смотрю в стане нет единого мнения. Поэтому хотелось бы услышать больше мнений по этому вопросу.

Вспомню свое упоминание о веб-сервисе, заодно и задам доп. вопрос. Вот веб-сервис не знает о классе Customer, он знает только CustomerID, и возвращает заказ клиента в виде объекта с полем CustomerID. В модели предметной области же я не могу получается использовать возвращаемые веб-сервисом объекты заказов. Во-первых, потому что не хочу связывать слой предметной области с классами из веб-сервиса, во-вторых потому что допустим я все-таки сделал хранение объекта Customer внутри объекта Order. Получается что мне после получения объекта заказа из веб-сервиса для дальнейшей работы с ним в слое модели предметной области надо конвертировать (копировать все поля с необходимыми преобразованиями) в объект класса Order?
Re[6]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 16.01.08 09:45
Оценка: +1
Здравствуйте, Trean, Вы писали:

T>Предложенный подход с моей точки зрения архитектурно неверен. Доменная модель не должна зависить от того куда и каким способом вы сериализуете данные (механизмов может быть несколько в одной программе), если только сериализация не единственное, что вы делаете с данными. Если механизм сериализации требует особенным образом заданных объектов используйте DTO.

Доменная модель, как и вся архитектура должна решать одну задачу — исполнить требования пользователя в максимально меньшие сроки с минимальным возможностей ошибок. Догматичность в архитектуре — вредна. Флейм когда использовать а когда не использовать DTO и что такое "подмена целей средствами", начинать не буду. Благо через поиск можно все найти.
Re[3]: Структура классов модели предметной области
От: ArchitectNewbie  
Дата: 16.01.08 17:02
Оценка: -1
Разовью свой вопрос. Аналогично из веб-сервиса приходят строки заказа. У меня же в модели предметной области свой класс OrderLine. Да, они могут быть фактически идентичными, но все-таки это разные классы, из совершенно разных мест. Как быть? Для дальнейшей работы с OrderLines из веб-сервиса конвертировать их в OrderLines модели предметной области?
Re[2]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 16.01.08 19:20
Оценка: +1
Здравствуйте, Blazkowicz, Вы писали:

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

А в чем проблема загрузить две сущности одним запросом?

B> А так же без особых проблем таскать обе сущности по всему слою бизнес логики. А иногда даже и дальше.

Вот как раз в случае ID таскать обе сущности можно куда угодно и как угодно, в отличии от ссылок.
Мы уже победили, просто это еще не так заметно...
Re[4]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 16.01.08 20:31
Оценка: +1
Здравствуйте, Blazkowicz, Вы писали:

B>http://rsdn.ru/forum/message/2798555.1.aspx
Автор: Blazkowicz
Дата: 16.01.08

То есть все-таки загрузить проблем нет? Да и вернуть вообщем-то тоже.

B>Каким образом? Держать оба объекта в кеше и каждый раз дергать по ID?

А это уж как кому в конкретном случае удобнее, в кеше или без кеша — дело десятое. Важно, что передать действительно можно куда угодно и как угодно, не оглядываясь на лишние потроха.
Мы уже победили, просто это еще не так заметно...
Re[8]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 17.01.08 16:32
Оценка: +1
Здравствуйте, Blazkowicz, Вы писали:

B>То что все таки упрется в используемые средства я ещё в исходном посте написал.

Об том и речь.. Зачем использовать, когда можно этого не делать? Проще получается.

B>Прокси возникают в рантайме.

Они возникают не из воздуха, надо написать механизм, который бкдет создавать эти прокси в рантайме.

B>Репозиторий же живет уже на этапе дизайна, тем самым прошивая собой всю архитектуру в целом.

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

B>ОК. Мне нужно передать клиенту набор из Order и Customer. У меня есть тулза которая сериализует объекты в SOAP. Предлагается передать объекты кучей, а клиент пусть сам разбирается какому заказу какой заказчик относится? Через ID, или порядок в списке, не важно. Важно что нужно разруливать.

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

B>Какие проблемы и какие мужественные решения?

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

B>1) Реюз модели. Модель можно использовать везде, даже там где нет репозитория.

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

B>2) Модель является единственным слоем на который завязана вся система.

Та же фигня, только в случае ID модель проще.

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

Нет. "Репозиторий" — обычный рядовой сервис, такой же как все остальные. Его наличие совершенно необязательно. А вот если в каком-то месте для солжного объекта не окажется проксей — все, приплыли.

B> Соответственно боремся за меньшую свзанность слоев системы.

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

B>3) Более понятный и простой код.

Гы..

B>Repository repository = Store.getRepository();

Вот эта строчка вылезает лишь тогда, когда сервис сам инстанцирует конкретный "репозиторий" (да и то, все таки IRepository), но так бывает редко (IoC, помнишь? )

Поэтому все сводится к:
B>
B>Customer customer = order.getCustomer();
B>//vs
B>Customer customer = repository.getCustomer(order);
B>

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

На самом деле — это я увлекся.. Надо признать, что есть разные приложения, и для каких-то сценариев действительно удобнее использовать сложные объекты. Но это, как правило, действительно сложные сценарии с нетривиальной логикой. В БД ориентированых приложениях, горадо проще тупо использовать ID, вместо ссылок и иметь модель практически точно копирующую БД. Все эти навороты со сложными объектами, проксями, ленивой загрузкой и прочими приседаниями идут только во вред, усложняя отладку, поддержку и запутывая логику приложения.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[23]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 23.01.08 07:56
Оценка: +1
Здравствуйте, MozgC, Вы писали:

MC>Я правильно понимаю что у вас 2 типа классов: один тип — обычный перенос сущности в ОО-вид, а другой — специально для отображения в гриде?

Нет такого класса, просто для перевода сущности в ОО-вид. Есть просто плоские данные и набор сервисов, которые этими данными обмениваются. View-сервис отображения, DAL — сервис персистентного хранения, какой-нибудь WebService — сервис коммуникации... Если одному из сервисов нужны данные в определенном виде, то он их получит.

MC>Т.е. если есть сущность "позиция заказа", то у вас будет класс OrderLine, который будет включать ManufacturerID, DealerID, ReferencePersonID и т.д.,

Если такой класс не будет нужен ни одному из сервисов, то такого класса не будет.
Мы уже победили, просто это еще не так заметно...
Re[25]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 23.01.08 21:05
Оценка: +1
Здравствуйте, adontz, Вы писали:

A>Ну лишний SQL запрос со всеми своими проблемами (а не блокирует ли этот запрос другие, а индексированы ли столбцы) добавляется.

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

A>Любые объекты, главное что не идентификаторы.

Ну объекты разными могут быть, могут плоскими, могут иерархическими — тебе без разницы, лишь бы объекты? И чем идентификаторы помешали?
При этом, заметь, у меня идентификаторов тоже не дофига.

A>LazyLoad с возможным упреждающим чтением.

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

A> Скажем если у меня попросили Manufacturer, очевидно, лучше считать всех сразу, а не по одному. Всё равно их мало, а понадобятся почти все.

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

A>Да я не фанатею от того чтобы грузить всё именно одним запросом.

А может стоило бы?..

A> Просто количество запросов не должно быть пропорционально количеству объектов. А количеству типов объектов, запросто.

Ну, смотри что получается: Строим мы красивую объектную модель безовсяких Id-шников. View она в таком виде не нужна, он все равно показывает ее плоско и по частям. Может быть вебсервису? Фигушки, там тоже довольно ограниченный набор данных нужен и опять-таки немного в другом виде. DAL, очевидно, ваще в пролете... Так ради кого вся эта красота?
Может быть это удобное универсальное представление, которое бизнес-логику продукта отражает и от этого всем хорошо? Давай попробуем на примере:
Вот есть у нас заказ, у заказа список продуктов, а у каждого продукта имеется Manufacturer, (у которого, в свою очередь, кстати, адрес фактический, адрес юридический, контактное лицо, список контрактов имеются, тоже ни разу не плоские объекты)... Ну, допустим, построили мы весь этот баобаб. Хорошо ли работается сейлзу? Да вообщем-то не плохо, иерархия ему привычная и насквозь удобная... И все бы зашибись, но тут приходит менеджер по закупкам, которому иерархия нужна ровно обратная Manufacturer, у которого по мимо адресов должен быть список производимых продуктов, а у каждого продукта список заказов... И где наша афигительная объектная модель? Очевидно с удобством представления тоже наелись.

Вышеприведенный пример наглядно демонстрирует тезис, что Data != Object. Данные — это данные, даже в объектном мире и не надо делать из них объекты. При однойи той же семантике, интерпретация данных может менятся, в зависимости от контекста, а упаковывая данные в сложный объект, ты прибиваешь гвоздями к данным конкретную трактовку. И потом приходится мучительно отдирать одно от другого.

A>Если данных не хватает они будут просто подгружены по требованию.

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

A>DAL сложнее стал, View — нет.

Как раз View-то в первую очередь стал сложнее. Нет формального контракта, декларирующего что именно он должен показывать и теперь именно в представлении болтается логика извлечения из развесистого объекта необходимых для показа данных в нужном виде. Приэтом протестировать эту логику так просто уже не получится.
Мы уже победили, просто это еще не так заметно...
Re[28]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 24.01.08 00:27
Оценка: +1
Здравствуйте, IB, Вы писали:

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

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

Просто не надо один запрос выставлять как решение проблемы.

A>>Почему лишаюсь? Просто вся эта кухня достаточно высоко (DAL клиента, читай Web-Service Client).

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

Не отдельно. ТОЛЬКО на клиенте.

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


В конкретном приложении для конкретного типа объектов кеш только один. Что касается многопользовательского изменения, то тут всё тоже решаемо. Во-первых, не удаляем ничего, только помечаем как удалённое. Тогда задание фамилии для удалённого пользователя будет восстанавливать пользователя. Во-вторых, пересчитываем кеш если в нём нет объекта с запрошенным ID. Только в очень экстремальных случаях этого не достаточно.

A>>Ку-ку, ID у веб-сервиса есть. Их только после DAL клиента нет.

IB>Причем здесь ID?

Ну ты же говоришь что ID у веб-сервиса нет, сразу объект. Я тебе говорю, что очень даже есть.

A>> Я нигде и не говорил что данная модель позволит тебе удобно искать во всех направлениях.

IB>Внимание, главный вопрос топика: Так зачем она нужна?

Во-первых, скрыть от Presentation и Business Logic детали загрузки данных. На уровне выше DAL эффективно загружать данные не создавая по запросу на каждый View практически нереальная задача. Да и зачем вопросы эффективной загрузки данных решать там?
Во-вторых, скрыть от Presentation и Business Logic детали хранения. ID мы вводим, как правило, специально, как удобное средство ссылки на объект. В предметной области есть очень даже однозначные PK, только они не числовые и работать с ними не удобно. Есть я, живой человек. То что я №2053 на РСДН — это проблема РСДН. У меня никакого номера в реальной жизни нет. У тебя тоже нет номера 343. Этот номер нельзя редактировать, нельзя смотреть. Никому кроме DAL он нафиг не нужен. Username тоже уникален, да только строка: и сравнивается дольше, и индексируется хуже, только от этого числовой идентификатор частью предметной области не становится.

A>> поиск всех продуктов выпускаем данным производителем ты, конечно, получишь у БД.

IB>Мне не нужен поиск, мне с производителем работать надо. Это тоже у БД?

Что значит работать? Ты развёрнуто задавай вопросы, мне угадывать трудновато.

A>> Просто уже можно просить только ID, остальная информация будет восстановлена на клиенте.

IB>Откуда она там возьмется и в каком виде она там лежит? И зачем просить ID отдельно, раундтрипы штука дорогая...

Ещё раз объясняю на более сложном примере. Один раз гружу и кеширую все товары, производителей и покупателей. Потом гружу продажи за май (производитель, товар, количество, покупатель, дата) и виде (ManufacturerID, ProductID, ProductCount, ClientID). Восстанавливаю объекты по ID из кеша. Гружу продажи за Июнь, за Апрель, клиенту Олег в полнолуние, в воскресные дни, в любой день с 12:00 до 14:00 и с сервера приходят уже только идентификаторы. Старт чуть дольше, работа заметно быстрее. Если пришёл ID которого в кеше нет, считываю данные в кеш заново. Выше DAL — сплошная непрекращающаяся объектная красота

IB>А что ты говоришь?


Что у меня объекты ТОЛЬКО на клиенте.

IB>Ты забыл про свой LazyLoading и другие ритуальные приседания.


А какое до этого всего дело View? Lazy Loading снаружи DAL не виден.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[43]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 31.01.08 01:40
Оценка: +1
...Видимо не судьба посмотреть на схему которую использует IB. Мне просто показалось что действительно в ней есть определенные плюсы, и тоже иногда кажется, что в случае полной объектной модели (т.е. с постоянной агрегацией объектов) появляются некоторые проблемы, которые мы потом начинаем решать. Но к сожалению так вот по отрывочным сообщениям лично мне с моим небольшим опытом сложно представить и понять как у IB все работает, а хотелось бы..
Структура классов модели предметной области
От: Аноним  
Дата: 14.01.08 19:19
Оценка:
Добрый день.

Посоветуйте, пожалуйста, как лучше и правильнее.

Есть класс заказа — Order. У заказа есть клиент, т.е. Customer. Так вот в классе Order хранить ли объект типа Customer? Или хранить CustomerID? Подозреваю, что правильнее первый вариант. Но второй вариант проще, иногда удобнее и быстрее. Например, из веб-сервиса нам может прийти объекта заказа с полем CustomerID т.к. веб-сервис не знает о типе Customer, и получается нам чтобы создать объект заказа типа Order нужно будет по CustomerID получать объект типа Customer (это будет занимать время, а потом информация о клиенте может и не понадобится). Как правильно?
Допустим, что все-таки правильнее хранить в классе Order объект типа Customer, а не CustomerID, тогда как загружать заказ из БД? Одним запросом с джоином из таблицы клиентов или отдельно загрузить данные только из таблицы заказов а потом отдельным запросом типа

order.Customer = CustomerRepository.GetCustomer(customerID);

?

Второй вопрос по задаче Order и OrderLine. Хранить ли IList<OrderLine> OrderLines в классе Order или нет? Если да, то как правильнее организовать работу? Когда загружать? А если в заказе 1000 позиций? А может они нам не понадобятся?

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

Спасибо!
Re[2]: Структура классов модели предметной области
От: Аноним  
Дата: 14.01.08 23:16
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

КЛ>Ок. Попробую помочь. Прежде всего, нужно определиться с обязанностями Ваших классов. Т.е. хорошо бы знать ответы на такие вопросы:


КЛ>

    КЛ>
  1. За что (за выполнение каких обязанностей) отвечает класс Customer?
    КЛ>
  2. За что (за выполнение каких обязанностей) отвечает класс Order?
    КЛ>
  3. За что (за выполнение каких обязанностей) отвечает класс OrderLine?
    КЛ>

  1. Customer — просто хранит информацию о клиенте — Имя, контактную информацию, ID в БД и т.д.
  2. Order — хранит информацию описывающую заказ — Т.е. номер заказа, ID заказа в БД и так же должен указывать на клиента которому он принадлежит.
  3. OrderLine — описывает единицу товара, т.е. описание, производителя, кол-во штук, цену закупки (типа себестоимости), и так же информацию о текущем состоянии этой единицы товара, например на какого поставщика она заказана, timestamp, состояние (в заказе, на складе, упакована) и т.д. — довольно объемный класс.

А>>Есть класс заказа — Order. У заказа есть клиент, т.е. Customer. Так вот в классе Order хранить ли объект типа Customer? Или хранить CustomerID? Подозреваю, что правильнее первый вариант.

КЛ>Почему правильнее хранить Customer'а? Совсем необязательно. В классе Order вполне достаточно хранить только CustomerID. И подгружать Customer'ов по мере необходимости. А чтобы не подгружать тех Customer'ов, которые уже когда-о были подгружены, можете завести класс Диспетчер Customer'ов, в котором организовать кэш. Как только Вам потребуется реальный Customer, Вы сразу же обращаетесь к Диспетчеру Customer'ов и передаёте ему CustomerID. А он либо подгружает его из БД, либо берёт из кэша.

Диспетчер — это аналог Repository, Manager ? Я правильно понимаю? А то названия у всех разные...

КЛ>Точно такой же механизм можете организовать и для заказов, введя Диспетчер Заказов.


А>>Второй вопрос по задаче Order и OrderLine. Хранить ли IList<OrderLine> OrderLines в классе Order или нет? Если да, то как правильнее организовать работу? Когда загружать? А если в заказе 1000 позиций? А может они нам не понадобятся?

КЛ>Тут Вам надо побеседовать с Клиентом и узнать, какое максимальное количество позиций может содержать Заказ? А также — процент таких заказов от общего числа заказов.

Заказы размером в 100 или 1000 позицию встречаются нередко. Средний заказ конечно позиций на 20, но 100 или 1000 это не особая редкость. Как лучше быть?

КЛ>Если заказы размером в 100 или 1000 позиций встречаются часто, то, конечно, не стоит подгружать все позиции. Если таких заказов очень мало, и основной процент заказов содержит 3 — 5 позиций, то, думаю, можно подгрузить все позиции при загрузке заказа.


КЛ>Если решите не подгружать все позиции сразу, то рекомендую Вам поступить точно так же, как и с Customer'ами — завести Диспетчер Позиций Заказа. Сам Заказ может содержать идентификаторы позиций. А вот если нужны будут данные конкретной позиции, то следует обратиться к Диспетчеру Позиций Заказа.


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

Допустим если я решу не читать все позиции сразу, то мне надо хранить вначале пустой IList<OrderLine> OrderLines в классе Order или тогда он вообще не нужен? А тогда при обращении к OrderLines проверять на null или лучше делать lazy load?...
Re: Структура классов модели предметной области
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 15.01.08 05:30
Оценка:
Здравствуйте, <Аноним>, Вы писали:

Взять ORM, к примеру, Hibernate и не заморачиваться, в том числе и на ленивую загрузку. В документации есть примеры, практически абсолютно по теме: 23.3. Customer/Order/Product или еще проще с помощью аннотаций (Hibernate Annotations) 2.2.5. Mapping entity bean associations/relationships.
Re[3]: Структура классов модели предметной области
От: Кирилл Лебедев Россия http://askofen.blogspot.com/
Дата: 15.01.08 13:29
Оценка:
Здравствуйте, Аноним, Вы писали:

А>

    А>
  1. Customer — просто хранит информацию о клиенте — Имя, контактную информацию, ID в БД и т.д.
    А>
  2. Order — хранит информацию описывающую заказ — Т.е. номер заказа, ID заказа в БД и так же должен указывать на клиента которому он принадлежит.
    А>
  3. OrderLine — описывает единицу товара, т.е. описание, производителя, кол-во штук, цену закупки (типа себестоимости), и так же информацию о текущем состоянии этой единицы товара, например на какого поставщика она заказана, timestamp, состояние (в заказе, на складе, упакована) и т.д. — довольно объемный класс.
    А>
Тогда это просто структуры (т.е. группы данных), но никак не классы. Потому что у них нет никаких обязанностей. Под обязанностью я понимаю некоторое действие, которое способствует достижению заданной цели. А эти структуры ничего не совершают, а только хранят.

Понятно, что на C# Вам может оказаться выгоднее объявить их как class, а не как struct. Но на C++ я бы точно предпочёл struct.

А>Диспетчер — это аналог Repository, Manager ? Я правильно понимаю? А то названия у всех разные...

Да, можно назвать и так.

А>Заказы размером в 100 или 1000 позицию встречаются нередко. Средний заказ конечно позиций на 20, но 100 или 1000 это не особая редкость. Как лучше быть?

Тогда OrderLines лучше подгружать по мере необходимости.

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

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

А>Допустим если я решу не читать все позиции сразу, то мне надо хранить вначале пустой IList<OrderLine> OrderLines в классе Order или тогда он вообще не нужен? А тогда при обращении к OrderLines проверять на null или лучше делать lazy load?...

Вообще не храните OrderLines внути Order. Как только Вам потребуются позиции заказа, просто обращайтесь к Диспетчеру Позиций Заказа, например, так:

IList<OrderLine> OrderLines = Диспетчер.Получить_Позиции_Заказа(anOrder.Id);
С уважением,
Кирилл Лебедев
Software Design blog — http://askofen.blogspot.ru/
Re[4]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 15.01.08 14:13
Оценка:
Здравствуйте, Trean, Вы писали:

T>Речь как я понимаю ведется о том, чтобы хранить объектную ссылку на объект в другом объекте или хранить pk этого объекта. Лучше конечно, ссылку, так правильнее с точки зрения ОО дизайна, так как в этом случае нет привязки к тому, как хранятся и идентифицируются объекты в хранилище (это не обязательно РСУБД и PK).

Но не правильно с практической точки зрения. В упомянутых в исходном посте Web сервисах благодаря ссылке Customer становится неотъемлимой частью заказа и должен будет пересылаться вместе с ним.
Re[5]: Структура классов модели предметной области
От: Trean Беларусь http://axamit.com/
Дата: 15.01.08 20:08
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


T>>Речь как я понимаю ведется о том, чтобы хранить объектную ссылку на объект в другом объекте или хранить pk этого объекта. Лучше конечно, ссылку, так правильнее с точки зрения ОО дизайна, так как в этом случае нет привязки к тому, как хранятся и идентифицируются объекты в хранилище (это не обязательно РСУБД и PK).

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

Предложенный подход с моей точки зрения архитектурно неверен. Доменная модель не должна зависить от того куда и каким способом вы сериализуете данные (механизмов может быть несколько в одной программе), если только сериализация не единственное, что вы делаете с данными. Если механизм сериализации требует особенным образом заданных объектов используйте DTO.
Re[4]: Структура классов модели предметной области
От: Аноним  
Дата: 16.01.08 02:07
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

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


Ну дело в том, что сегодня это просто структуры, а завтра там необходимо будет добавить методы, например перегрузить Equals() и добавить метод TakeSnapshot().
Re[4]: Структура классов модели предметной области
От: Аноним  
Дата: 16.01.08 02:18
Оценка:
Здравствуйте, Trean, Вы писали:

T>Речь как я понимаю ведется о том, чтобы хранить объектную ссылку на объект в другом объекте или хранить pk этого объекта. Лучше конечно, ссылку, так правильнее с точки зрения ОО дизайна, так как в этом случае нет привязки к тому, как хранятся и идентифицируются объекты в хранилище (это не обязательно РСУБД и PK).


Не буду спорить или наоборот соглашаться. Подсознательно мне кажется что раз уж мы строим модель предметной области и выделяем ее в отдельный слой, то и надо придерживаться работы с объектами модели предметной области а не с идентификаторами. С другой стороны действительно работа с ID зачастую практичнее и более подходящая в конкретном случае. Еще я думаю, что часто системы проектируются слишком сильно с учетом возможных каких-то будущих изменений в ущерб удобству работы сейчас. А ведь во многих случаях эти возможные изменения так никогда и не наступят. Вот вы написали про привязку к РСУБД. Какой шанс того что для хранилища будет использоваться что-то другое? Давайте посмотрим правде в глаза — шанс очень мал. Но зато вся система из-за этого может проектироваться с учетом этого возможного маловероятного изменения в будущем. По-моему это не совсем правильно.
Re[5]: Структура классов модели предметной области
От: Trean Беларусь http://axamit.com/
Дата: 16.01.08 09:41
Оценка:
Здравствуйте, Аноним, Вы писали:

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


T>>Речь как я понимаю ведется о том, чтобы хранить объектную ссылку на объект в другом объекте или хранить pk этого объекта. Лучше конечно, ссылку, так правильнее с точки зрения ОО дизайна, так как в этом случае нет привязки к тому, как хранятся и идентифицируются объекты в хранилище (это не обязательно РСУБД и PK).


А>Не буду спорить или наоборот соглашаться. Подсознательно мне кажется что раз уж мы строим модель предметной области и выделяем ее в отдельный слой, то и надо придерживаться работы с объектами модели предметной области а не с идентификаторами. С другой стороны действительно работа с ID зачастую практичнее и более подходящая в конкретном случае. Еще я думаю, что часто системы проектируются слишком сильно с учетом возможных каких-то будущих изменений в ущерб удобству работы сейчас. А ведь во многих случаях эти возможные изменения так никогда и не наступят. Вот вы написали про привязку к РСУБД. Какой шанс того что для хранилища будет использоваться что-то другое? Давайте посмотрим правде в глаза — шанс очень мал. Но зато вся система из-за этого может проектироваться с учетом этого возможного маловероятного изменения в будущем. По-моему это не совсем правильно.


В некотором смысле вы правы, не стоит заранее усложнять решение. Просто из моего опыта, из опыта работы с ORM-инструментами я для себя сделал вывод, что использование ссылок вместо id существенно упрощает жизнь особенно для богатой доменной модели. Такой подход дает огромное число полезных бенефитов, о которых Blazkowicz написал ниже.
Re[6]: Структура классов модели предметной области
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 16.01.08 11:02
Оценка:
Здравствуйте, Trean, Вы писали:

T>В некотором смысле вы правы, не стоит заранее усложнять решение. Просто из моего опыта, из опыта работы с ORM-инструментами я для себя сделал вывод, что использование ссылок вместо id существенно упрощает жизнь особенно для богатой доменной модели. Такой подход дает огромное число полезных бенефитов, о которых Blazkowicz написал ниже.

Да, как минимум это будет инвестицией в то, что когда мозги и руки таки дойдут до ORM или OODBMS, уже не нужно будет все переписывать.
Re[2]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 16.01.08 11:16
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Вообще в большинстве случаев все упирается в выбранный инструментарий. Буду ссылатся на Hibernate ORM как на образцово показательную тулзу.

+1
B>Но для тех кто выбирает хранение только ID, хочется отметить, что таким образом мы лишаем себя возможности загрузить обе сущности одним запросом.
Уверен?
B>А так же без особых проблем таскать обе сущности по всему слою бизнес логики. А иногда даже и дальше.
А нужно?
B>В случае с Hibernate мы можем хранить ссылку на объект, но при этом есть простраство для оптимизаций, как если бы мы хранили только ID.
Почти можно согласиться.
Вообще-же proxy и просто ссылка — это две разные вещи.

B>Тут как извечный выбор гармонии между памятью и производительностью. Выгребая всегда сущности вместе мы тратим излишнюю память, что на больших структурах в системах обслуживающих много пользователей критично. Выгребая сущности по отдельности мы теряем в производительности, так как используюется как минимум один запрос на каждый объект, вместо, например выборки нескольких объектов одним запросом через join.

B>В случае с Hibernate используется такая стратегия что все объекты по-умолчанию подгружаются отдельно. Тем самым использование памяти сводится к минимуму.
B>А потом уже в более зрелом приложении находятся участки, которые можно подвергнуть оптимизации и для них в методах DAO указывается что такие-то ассоциации нужно подгружать сразу.
Полностью соглашусь. Но тут есть еще другой вопрос. Ты подходишь к делу сразу с технологической точки зрения. А вот разделения понятий бизнес-объекта и классов иногда может привести к сипуке. Особенно в контексте отчуждаемых объектов с web сервиса.
Ну допустим, у нас есть документ. Неотьемлимой частью документа является автор. Точнее не сам автор, а его FIO. Если мы будем всегда работать с автором как с объектом через ссылку, то мы получим проблему того, что нам придется постоянно трансформировать данные при отчуждении. Вопрос даже не в эффективности памяти и производительности. Вопрос в сложности решения. Рефакторить — будет достаточно дорого, поскольку нам придется лезть во все использования данного объекта вплоть до визуальных форм. Не легче ли сразу в данном случае упростить решение, и сделать не некоторый объект, а некоторое поле неотъемлемым как того требует бизнес-логика.
Re[3]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 16.01.08 11:40
Оценка:
Здравствуйте, GlebZ, Вы писали:

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

GZ>Уверен?
Как бы да. Ну, загрузить-то мы их, к примеру, загрузим. А возвращать как? через out параметры? Нетипизированым списком или массивом? Форменное уродство с даункастингом получается.

B>>А так же без особых проблем таскать обе сущности по всему слою бизнес логики. А иногда даже и дальше.

GZ>А нужно?
Да.

B>>В случае с Hibernate мы можем хранить ссылку на объект, но при этом есть простраство для оптимизаций, как если бы мы хранили только ID.

GZ>Почти можно согласиться.
GZ>Вообще-же proxy и просто ссылка — это две разные вещи.
Это они фактически две разные вещи, а с точки зрения кода почти пофиг, что там.

GZ>Полностью соглашусь. Но тут есть еще другой вопрос. Ты подходишь к делу сразу с технологической точки зрения.

Не знаком с термином "технологическая точка зрения". Это что-то из "нанотехнологий"?

GZ>А вот разделения понятий бизнес-объекта и классов иногда может привести к сипуке.

Как это "разделение объектов и классов"?
GZ>Особенно в контексте отчуждаемых объектов с web сервиса.
Да, есть проблема с Web Service и с другими подобными фасадами. Опять же с Hibernate она решается на раз.

GZ>Ну допустим, у нас есть документ. Неотьемлимой частью документа является автор. Точнее не сам автор, а его FIO. Если мы будем всегда работать с автором как с объектом через ссылку, то мы получим проблему того, что нам придется постоянно трансформировать данные при отчуждении. Вопрос даже не в эффективности памяти и производительности. Вопрос в сложности решения. Рефакторить — будет достаточно дорого, поскольку нам придется лезть во все использования данного объекта вплоть до визуальных форм. Не легче ли сразу в данном случае упростить решение, и сделать не некоторый объект, а некоторое поле неотъемлемым как того требует бизнес-логика.

Смутно понимаю о чем речь. Хотя у меня сейчас именно такой проект. Весь интерфейс к приложению — веб сервисы.
Вообще особой проблемы нет. При сериализации всегда можно подкрутить чтобы минимизировать дерево объектов, а при сохранении куцые объекты либо не сохраняются вообще (односторонняя ассоциация), либо мерджатся по PK с объектом в кеше. Так что особых сложностей здесь я не наблюдаю. Главное чтобы тулза для с Web Service позволяла лимитировать передаваемые объекты.
Re[7]: Структура классов модели предметной области
От: Trean Беларусь http://axamit.com/
Дата: 16.01.08 13:36
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


T>>Предложенный подход с моей точки зрения архитектурно неверен. Доменная модель не должна зависить от того куда и каким способом вы сериализуете данные (механизмов может быть несколько в одной программе), если только сериализация не единственное, что вы делаете с данными. Если механизм сериализации требует особенным образом заданных объектов используйте DTO.

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

Проблема в том, что требования всегда меняются, иногда изменения можно предугадать, иногда нет. Выбрать такую архитектуру, которая удовлетворяя всем требованиям лучше всего позволяет адаптироваться под возможные изменения, это и есть "высший пилотаж" в работе архитектора. Догматизма в построении архитектуры не должно быть, согласен, но как правило у архитектора, есть набор типовых решений обкатанные на нескольких проектах, известны их + и — . Вот и у меня вопрос: стоит ли жертвовать удобством работы с объектами в слое бизнес-логики, и возможно также ее производительностью, только из-за того, что удобнее сериализовать "плоские" объекты чем объекты со сложными связями? Лично мне кажется — не стоит.
Re[4]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 16.01.08 15:13
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

GZ>>Вообще-же proxy и просто ссылка — это две разные вещи.

B>Это они фактически две разные вещи, а с точки зрения кода почти пофиг, что там.
С точки зрения наличия Hibernate. Я например не всегда могу себе позволить ORM. Мешают слишком слабоструктурированные данные.

B>Вообще особой проблемы нет. При сериализации всегда можно подкрутить чтобы минимизировать дерево объектов, а при сохранении куцые объекты либо не сохраняются вообще (односторонняя ассоциация), либо мерджатся по PK с объектом в кеше. Так что особых сложностей здесь я не наблюдаю. Главное чтобы тулза для с Web Service позволяла лимитировать передаваемые объекты.

Очевидно ты не понял. По постановке бизнес-объект Document всегда выводится с полем Author. В данном поле лежит ФИО автора. Естественно, при построении наличиствует и ссылка к справочнику физлиц через ссылку(ID). Однако, работать с данным полем, как принадлежащим элементу справочника — не удобно. Соответвенно, значительно проще его опубликовать как readonly поле. Если у тебя в интерфейсе Web сервиса объект с подобным полем, то сериализовать поле Author из объекта справочника в объект Document уже немного проблематичней.
Re[5]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 16.01.08 15:25
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>С точки зрения наличия Hibernate. Я например не всегда могу себе позволить ORM. Мешают слишком слабоструктурированные данные.

Не понятно.

B>>Вообще особой проблемы нет. При сериализации всегда можно подкрутить чтобы минимизировать дерево объектов, а при сохранении куцые объекты либо не сохраняются вообще (односторонняя ассоциация), либо мерджатся по PK с объектом в кеше. Так что особых сложностей здесь я не наблюдаю. Главное чтобы тулза для с Web Service позволяла лимитировать передаваемые объекты.

GZ>Очевидно ты не понял.
Очевидно ты не объяснил.

GZ>По постановке бизнес-объект Document всегда выводится с полем Author. В данном поле лежит ФИО автора. Естественно, при построении наличиствует и ссылка к справочнику физлиц через ссылку(ID). Однако, работать с данным полем, как принадлежащим элементу справочника — не удобно. Соответвенно, значительно проще его опубликовать как readonly поле. Если у тебя в интерфейсе Web сервиса объект с подобным полем, то сериализовать поле Author из объекта справочника в объект Document уже немного проблематичней.

Причем здесь какие-то справочники? Что значит "опубликовать как read-only поле"? Завязывай с изобретением терминилогии.
В чем проблема сериализовать два объекта в XML?
Re[8]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 16.01.08 15:26
Оценка:
Здравствуйте, Trean, Вы писали:

T>Проблема в том, что требования всегда меняются, иногда изменения можно предугадать, иногда нет. Выбрать такую архитектуру, которая удовлетворяя всем требованиям лучше всего позволяет адаптироваться под возможные изменения, это и есть "высший пилотаж" в работе архитектора. Догматизма в построении архитектуры не должно быть, согласен, но как правило у архитектора, есть набор типовых решений обкатанные на нескольких проектах, известны их + и — . Вот и у меня вопрос: стоит ли жертвовать удобством работы с объектами в слое бизнес-логики, и возможно также ее производительностью, только из-за того, что удобнее сериализовать "плоские" объекты чем объекты со сложными связями? Лично мне кажется — не стоит.

Дело в том, что вы в самом начале не упомянули что под ссылками имеете ввиду прокси Hibernate.(надеюсь вы это имели ввиду) Данная прокся берет на себя достаточно много работы. В случае отсутсвия таковой, нам приходится более пристально следить к разделению бизнес-объектов. И проводить ссылки между всеми объектами грозит большими проблемами особенно в транзакционности и кэшировании.
Re[6]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 16.01.08 15:44
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Что значит "опубликовать как read-only поле"? Завязывай с изобретением терминилогии.

Что тут непонятного? Пишу в терминах hibernate <property ... update="false" insert="false" />. Так понятней?

B>В чем проблема сериализовать два объекта в XML?

Зачем два. Один. Внимательней.
Re[7]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 16.01.08 15:55
Оценка:
Здравствуйте, GlebZ, Вы писали:

B>>Что значит "опубликовать как read-only поле"? Завязывай с изобретением терминилогии.

GZ>Что тут непонятного? Пишу в терминах hibernate <property ... update="false" insert="false" />. Так понятней?
И как это маппинг ассоциируется с "публикацией"? Ну, отлично. read-only property. В чем проблема-то, все равно не ясно.

B>>В чем проблема сериализовать два объекта в XML?

GZ>Зачем два. Один. Внимательней.
Вот и я спрашиваю зачем мне сериализовать
Document
{
AuthorFIO
Content
}
Когда можно с немешьм успехом провернуть тоже самое с
Document
{
Author
{
FIO
}
Content
}
Кто от этого пострадает?
Re[2]: Структура классов модели предметной области
От: ArchitectNewbie  
Дата: 16.01.08 16:18
Оценка:
Добрый вечер.

Подскажите, пожалуйста, по поводу моего вопроса, который я задал вчера:

AN>Вспомню свое упоминание о веб-сервисе, заодно и задам доп. вопрос. Вот веб-сервис не знает о классе Customer, он знает только CustomerID, и возвращает заказ клиента в виде объекта с полем CustomerID. В модели предметной области же я не могу получается использовать возвращаемые веб-сервисом объекты заказов. Во-первых, потому что не хочу связывать слой предметной области с классами из веб-сервиса, во-вторых потому что допустим я все-таки сделал хранение объекта Customer внутри объекта Order. Получается что мне после получения объекта заказа из веб-сервиса для дальнейшей работы с ним в слое модели предметной области надо конвертировать (копировать все поля с необходимыми преобразованиями) в объект класса Order?
Re[2]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 16.01.08 17:36
Оценка:
Здравствуйте, ArchitectNewbie, Вы писали:

Ты бы намекнул на чем пишешь.
Re[3]: Структура классов модели предметной области
От: ArchitectNewbie  
Дата: 16.01.08 17:56
Оценка:
GZ>Ты бы намекнул на чем пишешь.

C#, вебсервис на PHP
Re[3]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 16.01.08 19:35
Оценка:
Здравствуйте, IB, Вы писали:

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

IB>А в чем проблема загрузить две сущности одним запросом?
http://rsdn.ru/forum/message/2798555.1.aspx
Автор: Blazkowicz
Дата: 16.01.08


B>> А так же без особых проблем таскать обе сущности по всему слою бизнес логики. А иногда даже и дальше.

IB>Вот как раз в случае ID таскать обе сущности можно куда угодно и как угодно, в отличии от ссылок.
Каким образом? Держать оба объекта в кеше и каждый раз дергать по ID?
Re[5]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 16.01.08 22:16
Оценка:
Здравствуйте, IB, Вы писали:

IB>То есть все-таки загрузить проблем нет? Да и вернуть вообщем-то тоже.

Для кого как.

B>>Каким образом? Держать оба объекта в кеше и каждый раз дергать по ID?

IB>А это уж как кому в конкретном случае удобнее, в кеше или без кеша — дело десятое. Важно, что передать действительно можно куда угодно и как угодно, не оглядываясь на лишние потроха.
А потом как так получилось, что сквозь весь код протягивается красной нитью некий репозиторий. И на view по свойству никак не достать, репозиторий нужен. И в Web Service, объект не сериализовать, нужно предварительно все зависимости вытянуть, да структурировать.
В чем кайф-то?
Re[4]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 16.01.08 22:21
Оценка:
Здравствуйте, ArchitectNewbie, Вы писали:

AN>Разовью свой вопрос. Аналогично из веб-сервиса приходят строки заказа. У меня же в модели предметной области свой класс OrderLine. Да, они могут быть фактически идентичными, но все-таки это разные классы, из совершенно разных мест. Как быть? Для дальнейшей работы с OrderLines из веб-сервиса конвертировать их в OrderLines модели предметной области?

Модель надо стараться протащить через все уровни приложения. Какой сакраментальный смысл содержать сущности с одинаковым назначением?
Re[6]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 17.01.08 12:23
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Для кого как.

Скорее для какого инструмента, тут ты верно заметил.

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

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

B> И в Web Service, объект не сериализовать, нужно предварительно все зависимости вытянуть, да структурировать.

Не нужно.

B>В чем кайф-то?

Кайф в том, что сложный объект практически никогда не бывает нужен целиком. И если он у нас таки сложный, то либо совершенно кривая архитектура с недоконца инициализированными объектами, либо начинаются изнурительный приседания с Lazy Loading-ом и прочими обходными маневрами. Гибернейт, в этоми случае, конечно, приходит на помощь и делает большинство грязной работы, но зачем создавать себе проблемы и потом мужественно их решать с помощю сторонних инструментов, если можно просто этого не делать?
Так какие преимущества мы получаем, в случае использования сложных объектов, а не ID? За что боремся?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[7]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 17.01.08 12:46
Оценка:
Здравствуйте, IB, Вы писали:

B>>Для кого как.

IB>Скорее для какого инструмента, тут ты верно заметил.
То что все таки упрется в используемые средства я ещё в исходном посте написал.

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

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

B>> И в Web Service, объект не сериализовать, нужно предварительно все зависимости вытянуть, да структурировать.

IB>Не нужно.
ОК. Мне нужно передать клиенту набор из Order и Customer. У меня есть тулза которая сериализует объекты в SOAP. Предлагается передать объекты кучей, а клиент пусть сам разбирается какому заказу какой заказчик относится? Через ID, или порядок в списке, не важно. Важно что нужно разруливать.

B>>В чем кайф-то?

IB>Кайф в том, что сложный объект практически никогда не бывает нужен целиком. И если он у нас таки сложный, то либо совершенно кривая архитектура с недоконца инициализированными объектами, либо начинаются изнурительный приседания с Lazy Loading-ом и прочими обходными маневрами. Гибернейт, в этоми случае, конечно, приходит на помощь и делает большинство грязной работы, но зачем создавать себе проблемы и потом мужественно их решать с помощю сторонних инструментов, если можно просто этого не делать?
Какие проблемы и какие мужественные решения? Я так же не вижу сложностей забыть про слово Hibernate, а использовать тот же самый подход и с другими решениями. Нагенерить прокси в рантайме где-то ещё является проблемой?

IB>Так какие преимущества мы получаем, в случае использования сложных объектов, а не ID? За что боремся?

1) Реюз модели. Модель можно использовать везде, даже там где нет репозитория.
2) Модель является единственным слоем на который завязана вся система. Репозиторий же дополнительный слой, на который обратно надо завязывать всю систему. Соответственно боремся за меньшую свзанность слоев системы.
3) Более понятный и простой код.

Customer customer = order.getCustomer();
//vs
Repository repository = Store.getRepository();
Customer customer = repository.getCustomer(order);
Re[9]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 17.01.08 19:29
Оценка:
Здравствуйте, IB, Вы писали:

B>>То что все таки упрется в используемые средства я ещё в исходном посте написал.

IB>Об том и речь.. Зачем использовать, когда можно этого не делать?
Зачем использовать готовые средства?
IB>Проще получается.
Не факт.

B>>Прокси возникают в рантайме.

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

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

Код репозитория не сильно проще. Проблем с отладкой проксей не ещё возникало.

IB>Это в любом случае нужно разруливать,

Не согласен.

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

На клиенте не нужны прокси. Туда отдается только та часть дерева объектов которая нужна клиенту.

B>>Какие проблемы и какие мужественные решения?

IB>Проблема в том, что сложный объект имеет еще и логику, а таскать логику между слоями и уж, тем более, приложениями — гораздо сложнее.
Anemic data model rocks!!!

B>>1) Реюз модели. Модель можно использовать везде, даже там где нет репозитория.

IB>Вот как раз модель с ID использовать можно в принципе везде, вне зависимости от наличия "репозитория" и чего либо еще. Там голые данные, причем плоские, чем проще структура, тем проще ей манипулировать.
О какой структуре речь, если нет никакой структуры? Объекты-то не связаны. Датасеты какие-то получаются.

B>>2) Модель является единственным слоем на который завязана вся система.

IB>Та же фигня, только в случае ID модель проще.
Фигня не та же. Вся система завязывается и на репозиторий, без которого не получить связанные объекты.

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

IB>Нет. "Репозиторий" — обычный рядовой сервис, такой же как все остальные. Его наличие совершенно необязательно. А вот если в каком-то месте для солжного объекта не окажется проксей — все, приплыли.
Как это "наличие не обязательно"? А откуда тогда получать объекты?

B>> Соответственно боремся за меньшую свзанность слоев системы.

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

B>>Repository repository = Store.getRepository();

IB>Вот эта строчка вылезает лишь тогда, когда сервис сам инстанцирует конкретный "репозиторий" (да и то, все таки IRepository), но так бывает редко (IoC, помнишь? )
IRepository/Repository — C#
Repository/RepositoryImpl — Java


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

Нееее. Стоп. Репозиторий это не абстрактный DAO. Нам нужно где-то держать сущности, которые мы заранее вычитали (перфоманс тюнили) но они нам не везде нужны, чтобы их таскать по всему коду.

IB>На самом деле — это я увлекся..

Спасибо, что увлекся, а то все больше как-то игнорируют.

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

"БД ориентированое" приложение это то которое оперирует таблицами данных, а не деревьями объектов?
Re[9]: Структура классов модели предметной области
От: Trean Беларусь http://axamit.com/
Дата: 17.01.08 21:15
Оценка:
Здравствуйте, GlebZ, Вы писали:

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


T>>Проблема в том, что требования всегда меняются, иногда изменения можно предугадать, иногда нет. Выбрать такую архитектуру, которая удовлетворяя всем требованиям лучше всего позволяет адаптироваться под возможные изменения, это и есть "высший пилотаж" в работе архитектора. Догматизма в построении архитектуры не должно быть, согласен, но как правило у архитектора, есть набор типовых решений обкатанные на нескольких проектах, известны их + и — . Вот и у меня вопрос: стоит ли жертвовать удобством работы с объектами в слое бизнес-логики, и возможно также ее производительностью, только из-за того, что удобнее сериализовать "плоские" объекты чем объекты со сложными связями? Лично мне кажется — не стоит.

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

ссылки != прокси, ссылка может быть обычной прямой ссылкой, прокси надо только для lazy-loading больших коллекций и больших объектов, если надо ограничить выгружаемое дерево на клиентскую сторону (или за скоп транзакции). Следить надо только за двумя вещами — за тем, чтобы ограничить выбираемое дерево и за тем, чтобы не было попытки обратиться к прокси вне границ транзакции (когда сессия с коннектом уже умерла). Обе проблемы решаются.
Про транзакционность и кэширование поясни, что имел ввиду. Вроде есть кэширование первого уровня (в контексте сессии) и второго (какой-нибудь сторонний TreeCache). Я обычно использую короткие транзакции (запрос-начало транзакции-обработка-конец транзакции-отдача данных), хотя можно использовать extended context (session) и conversation model. Вроде все живы Не вижу проблемы.
Re[10]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 18.01.08 09:46
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Зачем использовать готовые средства?

Не готовые, а дополнительные... =)

B>Не факт.

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

B> Но зависимость на прокси меньше. Разница только в способе использования.

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

B>Проблем с отладкой проксей не ещё возникало.

Наверное потому что ты используешь гибернейт по стандартному сценарю..

B>На клиенте не нужны прокси.

А если нужны? Или, повторюсь, структура объекта другая?

B> Туда отдается только та часть дерева объектов которая нужна клиенту.

А что делать если часть дерева ненужна? Придумывать дополнительные DTO или предавать не доконца инициализированные объекты?
И за что боролись?

B>Anemic data model rocks!!!

Отож! =)

B>О какой структуре речь, если нет никакой структуры? Объекты-то не связаны. Датасеты какие-то получаются.

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

B>Фигня не та же. Вся система завязывается и на репозиторий, без которого не получить связанные объекты.

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

B>Как это "наличие не обязательно"? А откуда тогда получать объекты?

Из подходящей реализации этого хранилища.

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

В том-то и дело, что не нужен. Логика получения данных — ответственность BL, по остальным слоям расползаются уже загруженные и ни от чего независящие объекты. А вот в случае сложного объекта, он сам всегда зависит от прокси или должен быть гарантировано загружен целиком.

B>Нееее. Стоп. Репозиторий это не абстрактный DAO.

Почему нет?

B> Нам нужно где-то держать сущности, которые мы заранее вычитали (перфоманс тюнили) но они нам не везде нужны, чтобы их таскать по всему коду.

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

B>"БД ориентированое" приложение это то которое оперирует таблицами данных, а не деревьями объектов?

Это те, где нет нетривиальной бизнеслогики, которую удобно выражать через сложные ОО конструкции. В моей практике таковых подавляющее большинство..
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[11]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 18.01.08 10:28
Оценка:
Здравствуйте, IB, Вы писали:

B>>Проблем с отладкой проксей не ещё возникало.

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

B>>На клиенте не нужны прокси.

IB>А если нужны? Или, повторюсь, структура объекта другая?
Такая же структура.

IB>А что делать если часть дерева ненужна? Придумывать дополнительные DTO или предавать не доконца инициализированные объекты?

IB>И за что боролись?
Нет, на этапе сериализации решается что нужно клиенту а что нет. Например через WSDL. Клиент получает только то что описано в WSDL. Но в той же структуре данных без проксей. То что ему не нужно в этой структуре null.

B>>Нееее. Стоп. Репозиторий это не абстрактный DAO.

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

B>> Нам нужно где-то держать сущности, которые мы заранее вычитали (перфоманс тюнили) но они нам не везде нужны, чтобы их таскать по всему коду.

IB>И чем DAO для этого не годится? Это же тупо персистентный контейнер, логику кеширования вполне можно возложить и на него, как минимум в первом приближении, если не ожидается каких-то уж совсем противоестественных телодвижений.
Мне не нужен класс доступа к данным, мне нужен класс для связывания объектов модели. Размазывать DAO по всем слоям гораздо хуже чем проделывать тоже самое с репозиторием. DAO сильно завязан на реализацию. Потом всплывают вопросы вроде: "почему это view не может работать без базы данных".
Так вот этот класс в контексте этого топика я называю репозиторием.

B>>"БД ориентированое" приложение это то которое оперирует таблицами данных, а не деревьями объектов?

IB>Это те, где нет нетривиальной бизнеслогики, которую удобно выражать через сложные ОО конструкции. В моей практике таковых подавляющее большинство..
ОК. Я тебя понял. Твои аргумент ы не лешины смысла. Замечу все же что на большинстве проектов с которыми мне приходитс иметь дело удобно иметь именно ОО Иерархии модели. Нежели получать десяток не связанных сущностей для вывода на View.
Re[10]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 18.01.08 11:10
Оценка:
Здравствуйте, Trean, Вы писали:

T>ссылки != прокси, ссылка может быть обычной прямой ссылкой, прокси надо только для lazy-loading больших коллекций и больших объектов, если надо ограничить выгружаемое дерево на клиентскую сторону (или за скоп транзакции). Следить надо только за двумя вещами — за тем, чтобы ограничить выбираемое дерево и за тем, чтобы не было попытки обратиться к прокси вне границ транзакции (когда сессия с коннектом уже умерла). Обе проблемы решаются.

T>Про транзакционность и кэширование поясни, что имел ввиду. Вроде есть кэширование первого уровня (в контексте сессии) и второго (какой-нибудь сторонний TreeCache). Я обычно использую короткие транзакции (запрос-начало транзакции-обработка-конец транзакции-отдача данных), хотя можно использовать extended context (session) и conversation model. Вроде все живы Не вижу проблемы.
В принципе ты ответил на все вопросы, только их придется немного дополнить. Итак, у нас при Lazy Load задействуются 3 механизма — загрузка, транзакционность, кэширование. Насчет транзакционности — есть некоторое дополнительное правило. Объект в контексте транзакции не должен загружаться несколько раз (если конечно у тебя не явный блокировочный механизм, типа serialize транзакции БД). Не должно существовать два экземпляра одного объекта. Так как один объект может быть изменен(в контексте этой или другой транзакции), то другой объект имеет неверное состояние. Такие транзакции редкость, но если они встречаются, то Lazy Load нам мешает. Так как у нас нет явного механизма управления загрузкой, то должен быть построен механизм предотвращающий повторную загрузку объекта. А это также обозначает, что кэш первого уровня — это не контекст сессии, а контекст транзакции. Проблемы корректности общего кэша, описывать не буду. Они едины как с Lazy Load так и без оного.
Re[11]: Структура классов модели предметной области
От: GlebZ Россия  
Дата: 18.01.08 11:25
Оценка:
Здравствуйте, GlebZ, Вы писали:

Извини немного отвлекся. Что касается ссылок. Как результат, если у нас есть ссылка, то обрабатывать отдельно объект мы уже не сможем. В результате, при подгрузке — связанный объект всегда попадает в контекст транзакции. И для него придется выполнять все правила транзакционности. Ну заменили у Сustomer физический адрес. А в этот момент идут транзакции сохранения заказов. Версии не совпадают, транзакция заказов — откатывается. Кэширование. Кэширование идет практически всегда по ID. Вообще, в большинстве случаев, если тебе нужен тот или иной объект, то ты его ищешь в кэше по ID. Но объект сам по себе подвешен на ссылке родительского, и адресуется именно через родительский ID. Это не только неприятная нагрузка на кэш, но и требует чтобы при загрузке в кэш, мы проходили по всем идентификаторам.
Вобщем — удобства тут особо не вижу. Особенно в системах запрос-чтение-ответ. И в случае с производительностью — по сравнению с БД, работа с ссылками или hash таблицами нивелирована.
Re[12]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 18.01.08 12:18
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

IB>>А если нужны? Или, повторюсь, структура объекта другая?

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

B> Но в той же структуре данных без проксей. То что ему не нужно в этой структуре null.

То етсь не до конца инициализированный объект — а вот это уже конкретный косяк.

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

Это кеш. Кеш может быть реализован как отдельно, так и как часть DAL — сервиса персистентного ранения данных.

B> но таскать их мы с собой не можем, так как у объектов модели нет ссылок.

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

B>Мне не нужен класс доступа к данным, мне нужен класс для связывания объектов модели.

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

B> Размазывать DAO по всем слоям гораздо хуже чем проделывать тоже самое с репозиторием.

Да не размазывается там ничего, я уже писал. Про репозиторий/DAL знает только BL.

B> DAO сильно завязан на реализацию. Потом всплывают вопросы вроде: "почему это view не может работать без базы данных".

Не всплывают, так как view отлично работает без DAL.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re: Структура классов модели предметной области
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 19.01.08 08:37
Оценка:
А>Есть класс заказа — Order. У заказа есть клиент, т.е. Customer. Так вот в классе Order хранить ли объект типа Customer? Или хранить CustomerID?

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

А>Допустим, что все-таки правильнее хранить в классе Order объект типа Customer, а не CustomerID, тогда как загружать заказ из БД? Одним запросом с джоином из таблицы клиентов или отдельно загрузить данные только из таблицы заказов а потом отдельным запросом типа


Одним запросом можно заполнять составной набор данных (в .NET датасет из нескольких таблиц). Как это реализовывать в процедуре на базе — не важно, главное, чтобы оптимально по производительности.

А>Второй вопрос по задаче Order и OrderLine. Хранить ли IList<OrderLine> OrderLines в классе Order или нет? Если да, то как правильнее организовать работу? Когда загружать? А если в заказе 1000 позиций? А может они нам не понадобятся?


По месту.
... << RSDN@Home 1.2.0 alpha rev. 787>>
Re[13]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 20.01.08 13:05
Оценка:
Здравствуйте, IB, Вы писали:

OK. Ты меня практически убедил. Единственное что останусь при мнении что вариант с ID тоже не лишен недостатков. У меня такой вопрос. Есть где opensource решение или пример проекта посмотреть этот подход в действии?
Re[14]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 21.01.08 13:50
Оценка:
По поводу Customer vs CustomerID.
Допустим надо отобразить все заказы за сегодня, или за неделю и т.д. Таких заказов может быть 1000. Может больше. В случае если мы храним Customer, то мы можем забайндить и отображать order.Customer.Name. В случае с CustomerID — уже облом, не судьба будет увидеть имя клиента. Так что видимо хранение CustomerID отпадает, и надо делать либо LazyLoad с кешем на Customer, либо грузить его сразу.
Re[14]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 21.01.08 14:25
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Единственное что останусь при мнении что вариант с ID тоже не лишен недостатков.

Естетсвенно, серебряных пуль не существует и все имеет свою, довольно ограниченную, область применения.

B>У меня такой вопрос. Есть где opensource решение или пример проекта посмотреть этот подход в действии?

... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[15]: Структура классов модели предметной области
От: Константин Б. Россия  
Дата: 21.01.08 14:53
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>По поводу Customer vs CustomerID.

MC>Допустим надо отобразить все заказы за сегодня, или за неделю и т.д. Таких заказов может быть 1000. Может больше. В случае если мы храним Customer, то мы можем забайндить и отображать order.Customer.Name. В случае с CustomerID — уже облом, не судьба будет увидеть имя клиента. Так что видимо хранение CustomerID отпадает, и надо делать либо LazyLoad с кешем на Customer, либо грузить его сразу.

Либо биндить не объекты DAL, а какой-нибудь OrderList который будет представлять данные в нужном виде.
... << RSDN@Home 1.2.0 alpha rev. 787>>
Re[16]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 21.01.08 17:11
Оценка:
Здравствуйте, Константин Б., Вы писали:

КБ>Здравствуйте, MozgC, Вы писали:


MC>>По поводу Customer vs CustomerID.

MC>>Допустим надо отобразить все заказы за сегодня, или за неделю и т.д. Таких заказов может быть 1000. Может больше. В случае если мы храним Customer, то мы можем забайндить и отображать order.Customer.Name. В случае с CustomerID — уже облом, не судьба будет увидеть имя клиента. Так что видимо хранение CustomerID отпадает, и надо делать либо LazyLoad с кешем на Customer, либо грузить его сразу.

КБ>Либо биндить не объекты DAL, а какой-нибудь OrderList который будет представлять данные в нужном виде.


Этому OrderList'у видимо так же придется обращаться к БД (DAL) чтобы получить инфу для отображения, например имя клиента по его ID. Опять же падение производительности. Хотя в случае использования кеша может быть и небольшое. Т.е. эта ситуация похожа на LazyLoad с кешем.
Re[17]: Структура классов модели предметной области
От: Константин Б. Россия  
Дата: 21.01.08 17:37
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, Константин Б., Вы писали:




КБ>>Либо биндить не объекты DAL, а какой-нибудь OrderList который будет представлять данные в нужном виде.


MC>Этому OrderList'у видимо так же придется обращаться к БД (DAL) чтобы получить инфу для отображения, например имя клиента по его ID. Опять же падение производительности. Хотя в случае использования кеша может быть и небольшое. Т.е. эта ситуация похожа на LazyLoad с кешем.


Там можно сделать очень по разному. Никто не мешает загрузить сразу всех кастомеров оставивших заказы за сегодня, неделю и т. д. Это самый быстрый вариант. Главное что UI больше не зависит от того откуда что берется.
... << RSDN@Home 1.2.0 alpha rev. 787>>
Re[18]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 22.01.08 14:14
Оценка:
Вопрос к IB:

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

Например есть OrderLine, у которого есть CustomerID, ManufacturerID, DealerID, ReferencePersonID и т.д., на практике может встретиться еще и похлеще. И надо отобразить например 1000 таких OrderLine. Как такое отображаете?
Re[19]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 22.01.08 14:22
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Вопрос к IB:

А можно я отвечу?

MC>Я так понял, вы в основном храните ID в своих объектах, а не агрегируете другой объект.

MC>Как быть тогда в случае с отображением данных во View?
MC>Например есть OrderLine, у которого есть CustomerID, ManufacturerID, DealerID, ReferencePersonID и т.д., на практике может встретиться еще и похлеще. И надо отобразить например 1000 таких OrderLine. Как такое отображаете?

Вариантов вроде не один.
1) Репозиторий уезжает на view где используется так же как и в сервисах.
2) View имеет другую модель данных, которая создается, например, контроллером. Отдельная модель для view, ИМХО, один из немногих случаев обоснованого создания новой модели классов для той же модели данных.
3) Данные на View улетают в простом подготовленном виде, но без новых иерархий и репозиториев. Например несколькими массивами.
Re[20]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 22.01.08 14:40
Оценка:
MC>>Вопрос к IB:
B>А можно я отвечу?
Ну я даже не знаю...

MC>>Я так понял, вы в основном храните ID в своих объектах, а не агрегируете другой объект.

MC>>Как быть тогда в случае с отображением данных во View?
MC>>Например есть OrderLine, у которого есть CustomerID, ManufacturerID, DealerID, ReferencePersonID и т.д., на практике может встретиться еще и похлеще. И надо отобразить например 1000 таких OrderLine. Как такое отображаете?

B>Вариантов вроде не один.

B>1) Репозиторий уезжает на view где используется так же как и в сервисах.

Не понял, можно подробнее?

B>2) View имеет другую модель данных, которая создается, например, контроллером. Отдельная модель для view, ИМХО, один из немногих случаев обоснованого создания новой модели классов для той же модели данных.


Имеешь в виду создание класса типа OrderLineView и конвертацию списка OrderLine в OrderLineView?

B>3) Данные на View улетают в простом подготовленном виде, но без новых иерархий и репозиториев. Например несколькими массивами.


Тут тоже можно, пожалуйста, поподробнее?
Re[21]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 22.01.08 14:47
Оценка:
Здравствуйте, MozgC, Вы писали:

B>>1) Репозиторий уезжает на view где используется так же как и в сервисах.

MC>Не понял, можно подробнее?
ОК. Код в слое View обращается непосредственно к репозиторию чтобы достать Customer(.Name) имея Order.CustomerID/

B>>2) View имеет другую модель данных, которая создается, например, контроллером. Отдельная модель для view, ИМХО, один из немногих случаев обоснованого создания новой модели классов для той же модели данных.

MC>Имеешь в виду создание класса типа OrderLineView и конвертацию списка OrderLine в OrderLineView?
Да. OrdersScreen, OrdersForms etc.

B>>3) Данные на View улетают в простом подготовленном виде, но без новых иерархий и репозиториев. Например несколькими массивами.

MC>Тут тоже можно, пожалуйста, поподробнее?
Примерно такой код в контроллере:
prepareOrderList(Order[] orders)
{
   Customer[] customers = repository.getSortedCustomers(orders);
   MVCView.render(orders, customers);
}


Тут ещё некоторая двоякость термина View присутствует. Есть view как слой отоброжения данных (слой уровня Service, DAL).
А есть view — как слой паттерна MVC. Где MVC всего лишь способ реализовать View слой приложения.
Re[19]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 22.01.08 18:10
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Вопрос к IB:

А чего бы меня напрямую не спросить?

MC>Я так понял, вы в основном храните ID в своих объектах, а не агрегируете другой объект.

В основном да.

MC>Как быть тогда в случае с отображением данных во View?

Легко и непринужденно.

MC>Например есть OrderLine, у которого есть CustomerID, ManufacturerID, DealerID, ReferencePersonID и т.д., на практике может встретиться еще и похлеще. И надо отобразить например 1000 таких OrderLine. Как такое отображаете?

OrderLine — это объект для отображения агрегатной информации о заказе? Для отображения ID-шники, очевидно, не нужны, поэтому, скорее всего, объект будет иметь вид:
OrderLine
{
...
OrderId,
CustomerName,
ManufacturerName,
DealerName,
ReferencePersonName,
...
}
А в пределе — это может быть вообще анонимный тип.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[20]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 22.01.08 19:18
Оценка:
Здравствуйте, IB, Вы писали:

MC>>Вопрос к IB:

IB>А чего бы меня напрямую не спросить?

Напрямую это как?

MC>>Например есть OrderLine, у которого есть CustomerID, ManufacturerID, DealerID, ReferencePersonID и т.д., на практике может встретиться еще и похлеще. И надо отобразить например 1000 таких OrderLine. Как такое отображаете?

IB>OrderLine — это объект для отображения агрегатной информации о заказе?

OrderLine — это класс объекта представляющий конкретную линию (позицию) заказа, т.е. заказ Order включает в себя список позиций OrderLine, а так же общую информацию о заказе, типа номер заказа, дата заказа и т.д.

IB> Для отображения ID-шники, очевидно, не нужны, поэтому, скорее всего, объект будет иметь вид:

IB>OrderLine
IB>{
IB> ...
IB> OrderId,
IB> CustomerName,
IB> ManufacturerName,
IB> DealerName,
IB> ReferencePersonName,
IB> ...
IB>}
IB>А в пределе — это может быть вообще анонимный тип.

У нас наверное расхождение в понятиях. Вы, насколько я понимаю, представили OrderLine как класс специально созданный для отображения в гриде. Если да, то как вы создаете объекты такого типа и заполняете их? Если нет, то как вы например сохраняете такой объект в БД, если там имена а не ID из БД?
Re[21]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 22.01.08 20:14
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Напрямую это как?

Напрямую — это ответ на мое сообщение, а не Константин-а Б.

MC>OrderLine — это класс объекта представляющий конкретную линию (позицию) заказа, т.е. заказ Order включает в себя список позиций OrderLine, а так же общую информацию о заказе, типа номер заказа, дата заказа и т.д.

Ну, значит там будет еще ProductId фигурировать, ну или OrderLineId, если речь не о продуктах, а о какой-то абстрактной позиции...

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

Да, если не найдется других применений.

MC>Если да, то как вы создаете объекты такого типа и заполняете их?

Например так:
var lines = from o in orders 
            from c in customers
            ...
            where o.orderId == ... 
            select new {c.CustomerName, ...};



Или так:
OrderLines lines = Dal.GetOrderLinesByOrderId(orderId);



MC>Если нет, то как вы например сохраняете такой объект в БД, если там имена а не ID из БД?

Так как объект плоский, то по OrderLineId однозначно восстанавливаются все остальные ID-шники.
Мы уже победили, просто это еще не так заметно...
Re[22]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 22.01.08 20:56
Оценка:
Я правильно понимаю что у вас 2 типа классов: один тип — обычный перенос сущности в ОО-вид, а другой — специально для отображения в гриде?

Т.е. если есть сущность "позиция заказа", то у вас будет класс OrderLine, который будет включать ManufacturerID, DealerID, ReferencePersonID и т.д., и класс например OrderLineGrid, который будет вместо ID содержать ManufacturerName, DealerName и т.д.?
Re[22]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 22.01.08 21:08
Оценка:
Здравствуйте, IB, Вы писали:

IB>Например так:

IB>
IB>var lines = from o in orders 
IB>            from c in customers
IB>            ...
IB>            where o.orderId == ... 
IB>            select new {c.CustomerName, ...};
IB>


Иван, ну что за пряжки в сторону. Linq это же не показатель. Из твоего кода можно сделать вывод что ты загрузил заранее все orders, customers и теперь получаешь объекты по ID. Это не всегда возможно. Если не загрузил, то это ещё один метод в DAL. Зачем? Ну то есть не конкретно зачем этот один метод, а почему ты считаешь что приемлемо менять DAL в зависимости от того что в гриде отображается? Я считаю правильным передавать ID из веб-сервиса того же, это элементарно проще. Но вот в промежутке ClientDAL <-> ClientBLL уже только объекты должны быть. Разве нет?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[23]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 23.01.08 07:55
Оценка:
Здравствуйте, adontz, Вы писали:

A>Иван, ну что за пряжки в сторону.

??

A> Linq это же не показатель.

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

A> Из твоего кода можно сделать вывод что ты загрузил заранее все orders, customers и теперь получаешь объекты по ID.

Нельзя сделать такого вывода, Linq-овские запросы не плохо транслируются в БД.

A> Если не загрузил, то это ещё один метод в DAL.

Это не метод, это еще один способ обращения к DAL, равно как и клюбому другому сервису оперирующему коллекциями. Можно, конечно, назвать это и методом в некотором приближении, но все-таки это не совсем корректно.

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

Я не меняю DAL, я прежде всего, меняю объект однако вовсе не факт, что это приведет к изменениям в DAL.

A> Но вот в промежутке ClientDAL <-> ClientBLL уже только объекты должны быть. Разве нет?

какие объекты, в каком виде?

Смотри: Допустим у тебя есть полноценный объект OrderLine, у него вложенные объекты Customer, Manufacture, ect.., у Customer-а еще адрес какой-нибудь..
Теперь тебе надо отобразить тот же самый список — как ты весь этот зоопарк из базы грузить будешь? В этом случае у View нет формального контракта, что ему надо, а что нет — ты вынужден грузить все дерево и одним запросом уже не отделаешься. То есть, на практике, конечно, так не делают и грузят только то что надо, объект получается инициализирован не до конца, DAL, в конечном итоге, все равно меняется под View, но теперь, если View сломался потому что данных не хватает — концов не найдешь, плюс DAL стал заметно сложнее и у View появилась лишняя логика. Ну и зачем это надо?
Мы уже победили, просто это еще не так заметно...
Re[24]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 23.01.08 17:05
Оценка:
Здравствуйте, IB, Вы писали:

A>> Если не загрузил, то это ещё один метод в DAL.

IB>Это не метод, это еще один способ обращения к DAL, равно как и клюбому другому сервису оперирующему коллекциями. Можно, конечно, назвать это и методом в некотором приближении, но все-таки это не совсем корректно.

Ну лишний SQL запрос со всеми своими проблемами (а не блокирует ли этот запрос другие, а индексированы ли столбцы) добавляется.

A>> Но вот в промежутке ClientDAL <-> ClientBLL уже только объекты должны быть. Разве нет?

IB>какие объекты, в каком виде?

Любые объекты, главное что не идентификаторы.

IB>Смотри: Допустим у тебя есть полноценный объект OrderLine, у него вложенные объекты Customer, Manufacture, ect.., у Customer-а еще адрес какой-нибудь..

IB>Теперь тебе надо отобразить тот же самый список — как ты весь этот зоопарк из базы грузить будешь?

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

IB>В этом случае у View нет формального контракта, что ему надо, а что нет — ты вынужден грузить все дерево и одним запросом уже не отделаешься.


Да я не фанатею от того чтобы грузить всё именно одним запросом. Просто количество запросов не должно быть пропорционально количеству объектов. А количеству типов объектов, запросто.

IB>То есть, на практике, конечно, так не делают и грузят только то что надо, объект получается инициализирован не до конца, DAL, в конечном итоге, все равно меняется под View, но теперь, если View сломался потому что данных не хватает — концов не найдешь,


Если данных не хватает они будут просто подгружены по требованию.

IB>плюс DAL стал заметно сложнее и у View появилась лишняя логика. Ну и зачем это надо?


DAL сложнее стал, View — нет.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[26]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 23.01.08 21:46
Оценка:
Здравствуйте, IB, Вы писали:

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


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

IB>Ну объекты разными могут быть, могут плоскими, могут иерархическими


Уточни что такое в твоём понимании плоские объекты и иерархические.

A>>LazyLoad с возможным упреждающим чтением.

IB>А не дофига ли логики для такой, вообщем-то тривиальной задачи? При этом ты автоматом лишаешься возможности передать свой объект в другое окружение (допустим View стал удаленным), и добавляешь кучу геморроя на ровном месте, по обслуживанию всей этой кухни?

Почему лишаюсь? Просто вся эта кухня достаточно высоко (DAL клиента, читай Web-Service Client). Плюс я на самом деле экономлю ресурсы (тот же трафик), так как не считываю одни и те же данные в разных наборах. Имя клиента в списке клиентов и имя клиента в списке покупок дважды считаны не будут. Да и хранится они не будут дважды.

A>> Скажем если у меня попросили Manufacturer, очевидно, лучше считать всех сразу, а не по одному. Всё равно их мало, а понадобятся почти все.

IB>У тебя попросили его автоматом, при попытке показать список продуктов в заказе... Загружать его в каждый продукт? Или строить модель со ссылками на уникального производителя из всех продуктов?

У меня в клиенте (там где View) объект Product ссылается на объект Manufacturer. Если производитель один и тот же, то и ссылка на один и тот же (а не одинаковые!) объект.

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


А вот тут как раз всё хорошо. Пишем что-то вроде
bool SetAddress(
    Manufacturer manufacturer,
    string address)
{
    bool result = this._accessor.WebService.SetAddress(manufacturer.ID, address);

    if (result)
    {
        manufacturer.Address = address;
    }
    else
    {
        throw new DataAccessException(...);
    }
}

Объект manufacturer для конкретного производителя только один. Присваивание manufacturer.Address сгенерирует событие PropertyChanged, всякие IBindingList и компания сгенерируют Change (уже для всего объекта), View обновятся.

IB>Ну, смотри что получается: Строим мы красивую объектную модель безовсяких Id-шников. View она в таком виде не нужна, он все равно показывает ее плоско и по частям. Может быть вебсервису? Фигушки, там тоже довольно ограниченный набор данных нужен и опять-таки немного в другом виде. DAL, очевидно, ваще в пролете... Так ради кого вся эта красота?


Ку-ку, ID у веб-сервиса есть. Их только после DAL клиента нет.

IB>Вот есть у нас заказ, у заказа список продуктов, а у каждого продукта имеется Manufacturer, (у которого, в свою очередь, кстати, адрес фактический, адрес юридический, контактное лицо, список контрактов имеются, тоже ни разу не плоские объекты)... Ну, допустим, построили мы весь этот баобаб. Хорошо ли работается сейлзу? Да вообщем-то не плохо, иерархия ему привычная и насквозь удобная... И все бы зашибись, но тут приходит менеджер по закупкам, которому иерархия нужна ровно обратная Manufacturer, у которого по мимо адресов должен быть список производимых продуктов, а у каждого продукта список заказов... И где наша афигительная объектная модель? Очевидно с удобством представления тоже наелись.


Не, ты тёплое с мягким не путай. Я нигде и не говорил что данная модель позволит тебе удобно искать во всех направлениях. поиск всех продуктов выпускаем данным производителем ты, конечно, получишь у БД. Просто уже можно просить только ID, остальная информация будет восстановлена на клиенте.

IB>Вышеприведенный пример наглядно демонстрирует тезис, что Data != Object.


Вышеприведённый пример ничего не демонстрирует, ты не понял того что я говорю и благополучно доказал недостатки чего-то другого.

A>>Если данных не хватает они будут просто подгружены по требованию.

IB>Это если ты озаботился это дело написать, что само по себе не тривиальная и совершенно отдельная задача. При этом вся эта ленивость, в данном случае, является откровенной борьбой с собственноручно созданными проблемами.
if (!cache.ContainsKey(object.ID))
{
    ReloadCache()
}

?
столько я всегда напишу.

A>>DAL сложнее стал, View — нет.

IB>Как раз View-то в первую очередь стал сложнее. Нет формального контракта, декларирующего что именно он должен показывать и теперь именно в представлении болтается логика извлечения из развесистого объекта необходимых для показа данных в нужном виде. Приэтом протестировать эту логику так просто уже не получится.

Ну если обращение к свойству объекта это "логика извлечения из развесистого объекта необходимых для показа данных в нужном виде", то конечно да. Хотя так пафосно я бы не называл, это всё в дизайнере прямо делается
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[27]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 00:02
Оценка:
Здравствуйте, adontz, Вы писали:

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

Не передергивай. Здесь идет чтение набора, а не изменение одной записи и здесь один запрос от трех очень сильно отличается — это я тебе как краевед говорю.

A> Целостность данных вообще другими методами разруливается.

=)

A>Уточни что такое в твоём понимании плоские объекты и иерархические.

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

A>Почему лишаюсь? Просто вся эта кухня достаточно высоко (DAL клиента, читай Web-Service Client).

То есть, тебе эту логику еще отдельно на клиенте реализовывать надо, без нее у тебя этот объект просто не заработает — вот по этому и лишаешься.

A>У меня в клиенте (там где View) объект Product ссылается на объект Manufacturer. Если производитель один и тот же, то и ссылка на один и тот же (а не одинаковые!) объект.

Вот именно, и вот эту identity тебе тоже обеспечивать надо, она из воздуха не возьмется.

A>А вот тут как раз всё хорошо.

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

A>Ку-ку, ID у веб-сервиса есть. Их только после DAL клиента нет.

Причем здесь ID?

A>Не, ты тёплое с мягким не путай.

??

A> Я нигде и не говорил что данная модель позволит тебе удобно искать во всех направлениях.

Внимание, главный вопрос топика: Так зачем она нужна?

A> поиск всех продуктов выпускаем данным производителем ты, конечно, получишь у БД.

Мне не нужен поиск, мне с производителем работать надо. Это тоже у БД?

A> Просто уже можно просить только ID, остальная информация будет восстановлена на клиенте.

Откуда она там возьмется и в каком виде она там лежит? И зачем просить ID отдельно, раундтрипы штука дорогая...

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

А что ты говоришь?

A>столько я всегда напишу.

Столько, к сожалению, не достаточно.

A>Ну если обращение к свойству объекта это "логика извлечения из развесистого объекта необходимых для показа данных в нужном виде", то конечно да.

Ты забыл про свой LazyLoading и другие ритуальные приседания.
Мы уже победили, просто это еще не так заметно...
Re[26]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 24.01.08 10:14
Оценка:
Здравствуйте, IB, Вы писали:

IB>Вот есть у нас заказ, у заказа список продуктов, а у каждого продукта имеется Manufacturer, (у которого, в свою очередь, кстати, адрес фактический, адрес юридический, контактное лицо, список контрактов имеются, тоже ни разу не плоские объекты)... Ну, допустим, построили мы весь этот баобаб. Хорошо ли работается сейлзу? Да вообщем-то не плохо, иерархия ему привычная и насквозь удобная... И все бы зашибись, но тут приходит менеджер по закупкам, которому иерархия нужна ровно обратная Manufacturer, у которого по мимо адресов должен быть список производимых продуктов, а у каждого продукта список заказов... И где наша афигительная объектная модель? Очевидно с удобством представления тоже наелись.


ИМХО, с proxy подходом "афигительная объектная модель" здесь будет нормально работать.
Re[29]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 10:51
Оценка:
Здравствуйте, adontz, Вы писали:

A>Просто не надо один запрос выставлять как решение проблемы.

Боже, Рома... Позволь тебе напомнить, что это ты нашел в одном запросе какие-то проблемы, а я лишь пытаюсь показать, что не надо высасывать их из пальца.

A>Не отдельно. ТОЛЬКО на клиенте.

Из твоих собщений я так и не понял о каком клиенте идет речь и что в этот момент происходит на сервере.

A>В конкретном приложении для конкретного типа объектов кеш только один.

Везет тебе, даже в ORM общего назначения обычно парочку прикручивают, на всякий слуай. =)

A> Что касается многопользовательского изменения, то тут всё тоже решаемо.

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

A>Ну ты же говоришь что ID у веб-сервиса нет, сразу объект. Я тебе говорю, что очень даже есть.

Ты определенно сам с собой споришь.. Я нарисовал модель без ID-шника и сказал, что для веб-сервиса это не прокатит, а ты, в свою очередь, стал мне доказывать, что я не прав, потому что не прокатит, так как ID нужен. Это нормально? =)

A>Во-первых, скрыть от Presentation и Business Logic детали загрузки данных.

Детали загрузки скрыты и так, для этогоу нас есть DAL.

A> Да и зачем вопросы эффективной загрузки данных решать там?

Вопросы эффективности загрузки — задача сервиса хранения (DAL), задача BL — сформулировать для DAL в каком виде ему нужны данные.
А подход с объектами на данных скрывает и это от BL из-за чего приходится выдумывать различного рода приседания.

A>Во-вторых, скрыть от Presentation и Business Logic детали хранения.

Это ровно тоже самое, что и во-первых.
И какова цель у этого сокрытия? Сокрытие же не вещь в себе, какую проблему ты этим решаешь?

A>ID мы вводим, как правило, специально, как удобное средство ссылки на объект.

Объект у нас по определению должен обладать identity, это просто свойство любого объекта.

A> только от этого числовой идентификатор частью предметной области не становится.

Ну и что? Ты в серьез собираешься разруливать бизнес-логику оперируя только сущностями предметной области и не вводя дополнительных абстракций и вспомогательных механизмов?

A>Что значит работать?

Удалять, добавлять, редактировать. Это тоже делаем с БД или начинаем строить полноценную объектную модель?
Можешь сформулировать формальный критерий, когда с БД работаем, а когда начинаем дерево объектов городить?

A> Ты развёрнуто задавай вопросы, мне угадывать трудновато.

Ты не гадай, ты спрашивай..

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

Вообще-то номенклатура может быть очень дофигатой, все грузить будет накладно.

A>Потом гружу продажи за май (производитель, товар, количество, покупатель, дата) и виде (ManufacturerID, ProductID, ProductCount, ClientID).

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

A> Выше DAL — сплошная непрекращающаяся объектная красота

Аж в дрожь бросает...

A>Что у меня объекты ТОЛЬКО на клиенте.

А на сервере что? Сборная солянка?

A>А какое до этого всего дело View? Lazy Loading снаружи DAL не виден.

А кто DAL сообщает, что надо загрузить?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re: Структура классов модели предметной области
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.01.08 11:13
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Добрый день.


А>Посоветуйте, пожалуйста, как лучше и правильнее.


А>Есть класс заказа — Order. У заказа есть клиент, т.е. Customer. Так вот в классе Order хранить ли объект типа Customer? Или хранить CustomerID? Подозреваю, что правильнее первый вариант. Но второй вариант проще, иногда удобнее и быстрее. Например, из веб-сервиса нам может прийти объекта заказа с полем CustomerID т.к. веб-сервис не знает о типе Customer, и получается нам чтобы создать объект заказа типа Order нужно будет по CustomerID получать объект типа Customer (это будет занимать время, а потом информация о клиенте может и не понадобится). Как правильно?

Правильно — хранить реплику СustomerInfo внутри OrderInfo.
Наивные разработчики часто упускают фактор времени из моделирования. Дело в том, что клиент Иванова через полгода запросто может оказаться Синицыной. И что вы будете делать? По вашим отчетам, вы никогда ничего Ивановой не продавали. А у нее в руках есть распечатка, доказывающая обратное.
Или, вот к примеру, клиент ЗАО Сукин и Сыновья переехало в новый офис. А по вашим отчетам заказы пять лет назад были доставлены по адресу, которого на момент заказа не существовало в природе.

Конечно же, это не повод отказаться от сущности Customer совсем. Но такое дублирование информации позволит вам найти все заказы Синицыной, кем бы она там ни была в прошлом, и увидеть их такими, какими они были тогда.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[27]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 11:25
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>ИМХО, с proxy подходом "афигительная объектная модель" здесь будет нормально работать.

При самом удачном раскладе, придется как минимум, разруливать циклические зависимости и вообще, стараться всеми силами на запутаться в связях. И ради чего все это?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[28]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 24.01.08 13:17
Оценка:
IB, а как вы связываете объекты в программе если у вас только ID? Т.е. я так понимаю в вашей модели нет агрегации объектов. В классах Order, Customer и т.д. могут быть только простые типы? Я просто не могу представить в целом реализацию такой модели в проекте. Например вы создаете заказ:

...
Order order = new Order(...);
...
// Тут вы читаете в цикле например из excel-файла позиции заказа и создаете их
IList<OrderLine> orderLines = new List<OrderLine>();
...
OrderLine orderLine = new OrderLine(...);
...
orderLines.Add(orderLine);
...

Как вы связываете теперь Order и OrderLines? Или вы их не связываете, а просто сохраняете order в БД, после чего у него выставляется ID, а потом отдельно сохраняете orderLines, типа OrderLineRepository.AddOrderLines(order); ? Но связи кроме как "по смыслу" между объектами нет?

Про объектный подход с тянущимися иерархиями написано не так мало, а где можно почитать про реализацию подхода который используете вы?
Re[29]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 24.01.08 13:19
Оценка:
MC>Или вы их не связываете, а просто сохраняете order в БД, после чего у него выставляется ID, а потом отдельно сохраняете orderLines, типа OrderLineRepository.AddOrderLines(order); ?

Опечатался, OrderLineRepository.AddOrderLines(order, orderLines); (ну или order.AddOrderLines(orderLines)) *
Re[30]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 24.01.08 13:26
Оценка:
Здравствуйте, IB, Вы писали:

A>>Не отдельно. ТОЛЬКО на клиенте.

IB>Из твоих собщений я так и не понял о каком клиенте идет речь и что в этот момент происходит на сервере.

Клиент, это например, десктоп приложение обращающийся к веб-сервису. На сервере в этот момент происходит работа с плоскими объектами.

A>> Что касается многопользовательского изменения, то тут всё тоже решаемо.

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

Ну задача сохранения целостности данных вообще перпендикулярна обсуждаемому вопросу. Просто ты спросил, я ответил. Будут ли объекты на клиенте или ID, сути методов это не поменяет.

IB>И какова цель у этого сокрытия? Сокрытие же не вещь в себе, какую проблему ты этим решаешь?


Сокрытие не самоцель. Я уже говорил, экономятся ресурсы.

A>>ID мы вводим, как правило, специально, как удобное средство ссылки на объект.

IB>Объект у нас по определению должен обладать identity, это просто свойство любого объекта.

Да, но оно обычно уже есть в виде стрового имени. Ты 'Иван Бодягин', зачем нам ещё и 343? Можно и BLOB на 100Кб хранящий отпечаток пальца использовать, чем не identity?

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


Не не 'только'. Просто я и пихать их везде где не надо, просто потому что они есть, не собираюсь.

IB>Удалять, добавлять, редактировать. Это тоже делаем с БД или начинаем строить полноценную объектную модель?

IB>Можешь сформулировать формальный критерий, когда с БД работаем, а когда начинаем дерево объектов городить?

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

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

IB>Вообще-то номенклатура может быть очень дофигатой, все грузить будет накладно.

Ну можно грузить не всё, но всё же много. Что именно грузить, как оптимизировать, сильно зависит от природы объектов. Скажем продукты можно грузить группами по магазину, по производителю и т.п.

IB>О как. То есть ты вводишь еще один промежуточный слой, в кеше, который описывает все связи...


Ну да, кеш знает про связи объектов иначе как он их будет конструировать?

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


А чего ей по твоему не хватает для полноценности?

IB>Просто некая вспомогательная структура для обслуживания ОО-модели, как я понимаю. Зачем такие сложности?


Ну я сложностей-то особо не вижу. ИМХО по запросу на View — сложности. Запросов много, ими всеми надо руководить...

A>>Что у меня объекты ТОЛЬКО на клиенте.

IB>А на сервере что? Сборная солянка?

На сервере — ID и плоские объекты.

IB>А кто DAL сообщает, что надо загрузить?


Явно никто. DAL грузит всё, что уже нужно, но ещё не загружено.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[29]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 14:29
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>IB, а как вы связываете объекты в программе если у вас только ID?

По ID и связываю.

MC>Как вы связываете теперь Order и OrderLines? Или вы их не связываете, а просто сохраняете order в БД, после чего у него выставляется ID, а потом отдельно сохраняете orderLines, типа OrderLineRepository.AddOrderLines(order); ?

Так происходит в любом случае, БД-то никаких ссылок не знает, там есть только ID-шники.

MC>Про объектный подход с тянущимися иерархиями написано не так мало,

Мало. Про работу с данными в ОО вообще очень мало написано.

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

Например, Фаулеровский TableGetway — это вот примерно оно.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[31]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 14:29
Оценка:
Здравствуйте, adontz, Вы писали:

A>Клиент, это например, десктоп приложение обращающийся к веб-сервису. На сервере в этот момент происходит работа с плоскими объектами.

А почему такое разделение? По какой причине десктопу удобнее работать с полной объектной моделью, вместо плоских данных?

A>Ну задача сохранения целостности данных вообще перпендикулярна обсуждаемому вопросу. Просто ты спросил, я ответил. Будут ли объекты на клиенте или ID, сути методов это не поменяет.

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

A>Сокрытие не самоцель. Я уже говорил, экономятся ресурсы.

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

A>Да, но оно обычно уже есть в виде стрового имени. Ты 'Иван Бодягин', зачем нам ещё и 343?

Затем, что я могу поменять фамилию и все ссылки на меня отвалятся. Чем суррогатные ключи от естественных отличаются — знаешь?

A>Не не 'только'. Просто я и пихать их везде где не надо, просто потому что они есть, не собираюсь.

А где не надо и почему?

A>БД и объекты не вместо, а вместе.

В каком месте?

A> В любом случае, объектный кеш тут ни мешает и не помогает.

Зачем он тогда нужен?

A>Ну да, кеш знает про связи объектов иначе как он их будет конструировать?

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

A>А чего ей по твоему не хватает для полноценности?

Там ID-шники, вместо ссылок на объекты.

A>Ну я сложностей-то особо не вижу.

Сложности я тебе уже описал — ты устанешь все это в актуальном состоянии поддерживать, плюс с масштабируемостью у системы тоже будут проблемы.

A> ИМХО по запросу на View — сложности. Запросов много, ими всеми надо руководить...

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

A>На сервере — ID и плоские объекты.

А что мешает точно так же поступить на клиенте?

A>Явно никто. DAL грузит всё, что уже нужно, но ещё не загружено.

Откуда он узнает что нужно?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[28]: Структура классов модели предметной области
От: Blazkowicz Россия  
Дата: 24.01.08 14:44
Оценка:
Здравствуйте, IB, Вы писали:

B>>ИМХО, с proxy подходом "афигительная объектная модель" здесь будет нормально работать.

IB>При самом удачном раскладе, придется как минимум, разруливать циклические зависимости и вообще, стараться всеми силами на запутаться в связях. И ради чего все это?
Циклические зависимости разруливаются на раз из-за того что объект уже прокеширован и в случае циклического обхода в кеше уже оказывает объект с нужными ссылками, цикл замыкает без какого-либо особого контроля над этим. Путаницы никакой особой нет. На сколько знаю из хибера есть только сложность с сопоставлением закешированых единичных объектов с закешироваными коллекциями.
Re[32]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 24.01.08 15:06
Оценка:
Здравствуйте, IB, Вы писали:

A>>Клиент, это например, десктоп приложение обращающийся к веб-сервису. На сервере в этот момент происходит работа с плоскими объектами.

IB>А почему такое разделение? По какой причине десктопу удобнее работать с полной объектной моделью, вместо плоских данных?

У десктопа принципиально другие задачи. У него гораздо больше View представляющих разные комбинации свойств сущностей по-разному сгруппированные. Я не собираюсь тянуть это вниз до сервера. Если мне нужен ещё один View это не приведёт к изменению сервера.

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


В моём случае меняется вообще только клиент.

A>>Да, но оно обычно уже есть в виде стрового имени. Ты 'Иван Бодягин', зачем нам ещё и 343?

IB>Затем, что я могу поменять фамилию и все ссылки на меня отвалятся. Чем суррогатные ключи от естественных отличаются — знаешь?

Номер паспорта? У меня есть ещё и личный номер (не кино, а 01008018170, регистрационный номер меня как гражданина). И ты про отпечаток пальца забыл, BLOB на 100Кб.

A>>Не не 'только'. Просто я и пихать их везде где не надо, просто потому что они есть, не собираюсь.

IB>А где не надо и почему?

В интерфейсе не надо. Нигде на сайте нет числа 343.

A>>БД и объекты не вместо, а вместе.

IB>В каком месте?

Вместе в смысле не порознь, совместно, согласованно.

A>> В любом случае, объектный кеш тут ни мешает и не помогает.

IB>Зачем он тогда нужен?

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

IB>Тут вопрос вызывает не само знание о связях, а то в каком виде они представлены. В базе ведь все лежит по другому, зачем этот промежуточный вариант? И зачем из них что-то конструировать? Мы уже выяснили, что сконструированная объектная модель к дальнейшнему использованию, без изменений, не пригодна.. Так зачем?


Ну почему не пригодна? Очень даже пригодна. Для работы (удалить, добавить, поменять свойство) самое то.

A>>А чего ей по твоему не хватает для полноценности?

IB>Там ID-шники, вместо ссылок на объекты.

Да нет, там ссылки Я уже сто раз это написал. ID тоже хранятся, но только для общения с сервером.

A>>Ну я сложностей-то особо не вижу.

IB>Сложности я тебе уже описал — ты устанешь все это в актуальном состоянии поддерживать, плюс с масштабируемостью у системы тоже будут проблемы.

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

A>> ИМХО по запросу на View — сложности. Запросов много, ими всеми надо руководить...

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

Тут дело не в том, что у тебя точно '1 view' <-> '1 query'. Тут дело в том, что у тебя количество запросов с ростом view вообще говоря растёт примерно линейно. У меня не растёт совсем.

A>>На сервере — ID и плоские объекты.

IB>А что мешает точно так же поступить на клиенте?

То что у клиента множество сложных View и мне всё равно придётся получать по ID объекты. Так лучше это сделать один раз при загрузке, чем миллион раз при отображении. А у сервера нет таких сложных View совсем.

A>>Явно никто. DAL грузит всё, что уже нужно, но ещё не загружено.

IB>Откуда он узнает что нужно?

Ну раз попросили, значит нужно Загрузили товары. У товара есть производитель №734. Если в кеше нет такого производителя, то грузим его, потому что нужно.
Если ты про оптимизации типа "нужно было показать только название производителя, а мы загрузили ещё и адрес", то это пустяки по сравнению с многократной загрузкой названия в разных комбинациях.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[33]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 15:48
Оценка:
Здравствуйте, adontz, Вы писали:

A> У него гораздо больше View представляющих разные комбинации свойств сущностей по-разному сгруппированные.

О! Вот плоская модель как раз и дает больше гибкости в формировании комбинаций и группировок свойств.

A>Я не собираюсь тянуть это вниз до сервера. Если мне нужен ещё один View это не приведёт к изменению сервера.

А с чего ты взял, что кешировать можно только полноценные объекты?

A>В моём случае меняется вообще только клиент.

Так у нас и так речь только о клиенте.

A> И ты про отпечаток пальца забыл, BLOB на 100Кб.

Я ничего не забыл — это все не дает 100% гарантии твоей идентичности в рамках независимой системы. Номер паспорта поменять легче чем фамилию — это все вообще азбука, ты еще ИНН какой-нибцдь вспомни или SSN.

A>В интерфейсе не надо. Нигде на сайте нет числа 343.

Так в интерфейс эти числа никто и не предлагает выводить.

A>Вместе в смысле не порознь, совместно, согласованно.

В каком месте они "не порознь" и как именно?

A>Он нужен чтобы предоставить более высокостоящим слоям стабильный интерфейс прозрачной загрузки данных.

Тоесть мы из модели получили интерфейс загрузки данных? забавно...

A> Может не максимально эффективно а рамках одного запроса, зато весьма эффективно в рамках приложения

Меня терзают смутные сомнения.

A>, да и не надо что-либо переписывать при добавлении нового View.

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

A>Ну почему не пригодна?

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

A>Да нет, там ссылки

Вот потому и не полноценная объектная. Ты хоть нить разговора-то не теряй.

A>Да с масштабируемостью как раз всё лучше, так как меньше данных предаётся и запросов на чтение меньше гораздо.

Ты это будешь кластеру рассказывать.

A> Это можно элементарно подсчитать. Плюс тут ещё и то, что сервер практически не трогается. Вот поддерживать на сервере запросы специфические для клиентских View можно действительно замучаться.

....
A>Тут дело не в том, что у тебя точно '1 view' <-> '1 query'. Тут дело в том, что у тебя количество запросов с ростом view вообще говоря растёт примерно линейно. У меня не растёт совсем.
Пойми простую вешь — количество запросов к БД/серверу не зависит от представления объектов в памяти. Никак не зависит, вообще.
Просто создание полноценной объектной модели — это, в большинстве случаев, лишний промежуточный шаг и зачем его делать мне не понятно.

A>То что у клиента множество сложных View и мне всё равно придётся получать по ID объекты. Так лучше это сделать один раз при загрузке, чем миллион раз при отображении.

См выше.

A>Ну раз попросили, значит нужно

То есть кто-то таки должен попросить?

A>Если ты про оптимизации типа "нужно было показать только название производителя, а мы загрузили ещё и адрес", то это пустяки по сравнению с многократной загрузкой названия в разных комбинациях.

Да нет никакой многократной загрузки.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[34]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 24.01.08 16:08
Оценка:
Здравствуйте, IB, Вы писали:

A>> У него гораздо больше View представляющих разные комбинации свойств сущностей по-разному сгруппированные.

IB>О! Вот плоская модель как раз и дает больше гибкости в формировании комбинаций и группировок свойств.

Ну тут как-то всё руками приходится делать. Непрозрачно.

A>>Я не собираюсь тянуть это вниз до сервера. Если мне нужен ещё один View это не приведёт к изменению сервера.

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

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

A>> И ты про отпечаток пальца забыл, BLOB на 100Кб.

IB>Я ничего не забыл — это все не дает 100% гарантии твоей идентичности в рамках независимой системы. Номер паспорта поменять легче чем фамилию — это все вообще азбука, ты еще ИНН какой-нибцдь вспомни или SSN.

Во-о-от. Но несмотря на удобство числового ID он частью предметной области всё равно не станет.

IB>Так в интерфейс эти числа никто и не предлагает выводить.


Я предлагаю Presentation даже не давать к ним обращаться. Ну так, заодно. Не самоцель.

A>>Вместе в смысле не порознь, совместно, согласованно.

IB>В каком месте они "не порознь" и как именно?

Объектная модель и данные в БД поддерживаются в согласованном состоянии без многократного считывания из БД.

A>>Он нужен чтобы предоставить более высокостоящим слоям стабильный интерфейс прозрачной загрузки данных.

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

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

A>>, да и не надо что-либо переписывать при добавлении нового View.

IB>Не надо переписывать только в том случае, если ты уже написал всю инфраструктуру и, ключевое, имеющаяся иерархия объектов устраивает новый view.

А кто у View спрашивает, собственно? View 100 раз на дню меняется, под View менять внутренности замучаешься. Да и внутренности будут не очень.

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


Меня терзают смутные сомнения

A>>Да нет, там ссылки

IB>Вот потому и не полноценная объектная. Ты хоть нить разговора-то не теряй.

Я не понял. Нет ссылок, модель неполноценная. Есть ссылки (как у меня), модель всё равно неполноценная. Доктор, определяйтесь.

A>>Да с масштабируемостью как раз всё лучше, так как меньше данных предаётся и запросов на чтение меньше гораздо.

IB>Ты это будешь кластеру рассказывать.

А кластер тут причём? Кластер для клиента должен быть абсолютно прозрачен, иначе это наколеночная поделка.

A>>Тут дело не в том, что у тебя точно '1 view' <-> '1 query'. Тут дело в том, что у тебя количество запросов с ростом view вообще говоря растёт примерно линейно. У меня не растёт совсем.

IB>Пойми простую вешь — количество запросов к БД/серверу не зависит от представления объектов в памяти. Никак не зависит, вообще.

Не самих запросов, конечно. Извини, если запутал. Разных ТИПОВ запросов.

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


Ну ты ИМХО преувеличиваешь трудоёмкость этого шага.

A>>Ну раз попросили, значит нужно

IB>То есть кто-то таки должен попросить?

Да, просьбой является неразрешённая внешняя ссылка (foreign key).

A>>Если ты про оптимизации типа "нужно было показать только название производителя, а мы загрузили ещё и адрес", то это пустяки по сравнению с многократной загрузкой названия в разных комбинациях.

IB>Да нет никакой многократной загрузки.

Ну как же нет, когда ты предлагаешь половинки объектов грузить.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[35]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 24.01.08 22:59
Оценка:
Здравствуйте, adontz, Вы писали:

A>Ну тут как-то всё руками приходится делать. Непрозрачно.

Руками придется все равно делать. А вот "прозрачность" — это косяк.

A>Конечно не только, а смысл делать кучу кешей.

Кто говорит про кучу?

A>Во-о-от. Но несмотря на удобство числового ID он частью предметной области всё равно не станет.

Еще раз: Ну и что? Ты собрался разруливать бизнес логику оперируя исключительно сущностями предметной области?

A>Я предлагаю Presentation даже не давать к ним обращаться. Ну так, заодно. Не самоцель.

Ну и какая в этом цель, если не само?

A>Объектная модель и данные в БД поддерживаются в согласованном состоянии без многократного считывания из БД.

Волшебным образом?

A>>>Он нужен чтобы предоставить более высокостоящим слоям стабильный интерфейс прозрачной загрузки данных.

IB>>То есть мы из модели получили интерфейс загрузки данных? забавно...
A>Из DAL.
Причем здесь DAL? Речь о модели.

A> DAL строит модель по требованию, так, чтобы все внешние ссылки были разрешены.

По требованию кого? Кто обратится к DAL и скажет что этот объект надо загрузить?

A>А кто у View спрашивает, собственно?

Тогда ради кого мы городим объектную модель? Кому с ней удобно работать?

A>Меня терзают смутные сомнения

Ты не терзайся, ты проверь.

A> Есть ссылки (как у меня), модель всё равно неполноценная. Доктор, определяйтесь.

ManufacturerID, OrderID ect — это не ссылки.

A>А кластер тут причём? Кластер для клиента должен быть абсолютно прозрачен, иначе это наколеночная поделка.

Это я про сервер.

A>Не самих запросов, конечно. Извини, если запутал. Разных ТИПОВ запросов.

Все равно не зависит, никак.

A>Ну ты ИМХО преувеличиваешь трудоёмкость этого шага.

Во первых, она отлична от нуля и шаг этот лишний. А во-вторых, это еще и код запутывает.

A>Да, просьбой является неразрешённая внешняя ссылка (foreign key).

Откуда он узнает, что ее надо разрешить?

A>Ну как же нет, когда ты предлагаешь половинки объектов грузить.

Ты же уже согласился с тем, что нет проблем закешировать то что надо.
Мы уже победили, просто это еще не так заметно...
Re[36]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 24.01.08 23:16
Оценка:
Здравствуйте, IB, Вы писали:

A>>Ну тут как-то всё руками приходится делать. Непрозрачно.

IB>Руками придется все равно делать. А вот "прозрачность" — это косяк.

Руками лень. Прозрачность — фича.

A>>Конечно не только, а смысл делать кучу кешей.

IB>Кто говорит про кучу?

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

A>>Во-о-от. Но несмотря на удобство числового ID он частью предметной области всё равно не станет.

IB>Еще раз: Ну и что? Ты собрался разруливать бизнес логику оперируя исключительно сущностями предметной области?

Я собрался разруливать бизнес-логику не обращаясь к ID. То что в БД выражается через ID и FK, в объектной модели будет выражаться через уникальный объект и ссылку на объект. Он где-то внутри будет хранить ID, да только показывать его не будет. Совсем. И никаких проблем такой подход не вызывает. Абсолютно. Ни разу ещё не потребовался искусственный ID где либо кроме DAL.

A>>Я предлагаю Presentation даже не давать к ним обращаться. Ну так, заодно. Не самоцель.

IB>Ну и какая в этом цель, если не само?

Инкапсуляция, защита от дурака, назови как хочешь. Главное, что если что-то где-то не нужно, то этого там попросту нет.

A>>Объектная модель и данные в БД поддерживаются в согласованном состоянии без многократного считывания из БД.

IB>Волшебным образом?

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

IB>Причем здесь DAL? Речь о модели.


Причём тут модель? Речь о DAL! Я о модели вообще ни слова не сказал.

A>> DAL строит модель по требованию, так, чтобы все внешние ссылки были разрешены.

IB>По требованию кого? Кто обратится к DAL и скажет что этот объект надо загрузить?

Любой объект у которого есть неразрешённая внешняя ссылка.

A>>А кто у View спрашивает, собственно?

IB>Тогда ради кого мы городим объектную модель? Кому с ней удобно работать?

Ради View. Просто View нам не навязывает структуру DAL.

A>> Есть ссылки (как у меня), модель всё равно неполноценная. Доктор, определяйтесь.

IB>ManufacturerID, OrderID ect — это не ссылки.

ManufacturerID, OrderID приходят с сервера и по ним получаются из кеша объекты Manufacturer, Order. На них и указывают ссылки. Что же тут непонятного?!

A>>А кластер тут причём? Кластер для клиента должен быть абсолютно прозрачен, иначе это наколеночная поделка.

IB>Это я про сервер.

А на сервере у нас объектной модели нет, я уже несколько раз это сказал.

A>>Не самих запросов, конечно. Извини, если запутал. Разных ТИПОВ запросов.

IB>Все равно не зависит, никак.

Ну извини, если ты для View всё достаёшь одним запросом, то как же с ростом разных View не растёт количество разных запросов? Нестыковочка.

A>>Да, просьбой является неразрешённая внешняя ссылка (foreign key).

IB>Откуда он узнает, что ее надо разрешить?

Её всегда надо разрешать. Если не в объект, то в его LazyLoad декоратор. То есть null там вообще никогда не будет.

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


Ну на ассемблере всё написать тоже проблемы нет. Мы же обсуждаем оптимальное отношение трудозатраты/результат, а не способность отдельных фанатиков творить крупномасштабные глупости.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[37]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 25.01.08 08:13
Оценка:
Здравствуйте, adontz, Вы писали:

A>Руками лень.

Фигасе — наворотить кучу кода на ровном месте ему не лень, а явно метод вызвать — лень?

A>Прозрачность — фича.

Дороговато для фичи и уж больно геморно.

A>Ну если больше одного для конкретного типа, уже много

Я не понимаю, до тебя дошло, что лишних запросов там не будет или нет?

A>Тем более что мотивация это по-разному недогруженные объекты.

Объекты как раз догружены, ровно какие надо и ничего лишнего.

A>Я собрался разруливать бизнес-логику не обращаясь к ID.

И при чем тут является ID частью предметной области или нет?

A> То что в БД выражается через ID и FK, в объектной модели будет выражаться через уникальный объект и ссылку на объект.

Какие преимущества это дает? У тебя уже есть готовая модель данных с ID, ради чего уходить от нее и строить некую промежуточную абстракцию, которая напрямую ни для чего не пригодна, если с тем же успехом можно использовать уже имеющуюся модель?

A>Он где-то внутри будет хранить ID, да только показывать его не будет.

Кому показывать?

A> Совсем. И никаких проблем такой подход не вызывает.

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

A>Инкапсуляция, защита от дурака, назови как хочешь. Главное, что если что-то где-то не нужно, то этого там попросту нет.

Это не инкапсуляция и от какого дурака тут защищаться — я слабо представляю. А вот то что "это" там не нужно — еще большой вопрос.

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

Ну и фиг с ними? Отлично..

A>Фактически у нас есть полная БД и её частичная реплика.

Так зачем эту реплику делать в другом виде, отличном от того как она лежит в базе?

A>Причём тут модель? Речь о DAL! Я о модели вообще ни слова не сказал.

Ты топик-то перечитай...

A>Любой объект у которого есть неразрешённая внешняя ссылка.

То есть модель знает о DAL, зависит от него и умеет себя загружать. Тебя это не смущает?

A>Ради View.

View — то как раз удобнее работать с плоской моделью, когда ему подпихивается ровно то, что надо показать.

A> Просто View нам не навязывает структуру DAL.

Структуру DAL навязывает бизнес-логика.

A>ManufacturerID, OrderID приходят с сервера и по ним получаются из кеша объекты Manufacturer, Order. На них и указывают ссылки. Что же тут непонятного?!

Ты там описывал один объект с перечнем ID-шников, такой объект не нужен ни БД, ни объектной модели — вообще получается какая-то третья промежуточная структура, что и вызывает вопросы..

A>Ну извини, если ты для View всё достаёшь одним запросом, то как же с ростом разных View не растёт количество разных запросов? Нестыковочка.

Тебе еще раз рассказать, что любая модель отлично кешируется, вне зависимости от ее представления в памяти?
Прелесть в том, что я в любой момент могу один конкретный запрос, для конкретной View (или чего либо другого) критичный по производительности, или другим параметрам, опустить до уровня БД/сервера, а могу спокойно кешировать копию оригинальных данных и строить нужные структуры в памяти. Как в этом случае будешь изворачиваться ты, со своей "прозрачностью" — я слабо представляю.

A>Её всегда надо разрешать.

Иными словами модель прибита к DAL.

A> Мы же обсуждаем оптимальное отношение трудозатраты/результат, а не способность отдельных фанатиков творить крупномасштабные глупости.

У меня уже появляются определенные сомнения.. )
Мы уже победили, просто это еще не так заметно...
Re[37]: Структура классов модели предметной области
От: Ziaw Россия  
Дата: 25.01.08 08:17
Оценка:
Здравствуйте, adontz, Вы писали:

A>>>Да, просьбой является неразрешённая внешняя ссылка (foreign key).

IB>>Откуда он узнает, что ее надо разрешить?

A>Её всегда надо разрешать. Если не в объект, то в его LazyLoad декоратор. То есть null там вообще никогда не будет.

А как LazyLoad декоратор считывает данные на клиенте? Как быть с транзакционной целостностью? Как вы решаете вопрос column-level security? Как решается вопрос, о изменениях объектов которые могут изменяться только по каким-то правилам бизнес-логики?

Именно эти вопросы я так и не смог решить, отказавшись от объектной модели на клиенте, т.е. сервер работает в рамках объектной модели, на клиента отдаются DTO, часто заточенные под view, на сервер отправляются DTO часто заточенные под определенную бизнес-транзакцию. Есть подозрение что, я поимел недостатки обоих подходов, но также получил явные их преимущества.
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[38]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 25.01.08 08:57
Оценка:
Здравствуйте, IB, Вы писали:

A>>Тем более что мотивация это по-разному недогруженные объекты.

IB>Объекты как раз догружены, ровно какие надо и ничего лишнего.

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

A>> То что в БД выражается через ID и FK, в объектной модели будет выражаться через уникальный объект и ссылку на объект.

IB>Какие преимущества это дает? У тебя уже есть готовая модель данных с ID, ради чего уходить от нее и строить некую промежуточную абстракцию, которая напрямую ни для чего не пригодна, если с тем же успехом можно использовать уже имеющуюся модель?

Удобство обращения к данным. Я в объектной модели могу элементарно забиндить значение столбца грида на свойство.

A>>Он где-то внутри будет хранить ID, да только показывать его не будет.

IB>Кому показывать?

BLL/UI показывать не будет.

A>>Фактически у нас есть полная БД и её частичная реплика.

IB>Так зачем эту реплику делать в другом виде, отличном от того как она лежит в базе?

А какая разница в каком она виде? Её вид и возможность рассогласования абсолютно не связаны.

A>>Любой объект у которого есть неразрешённая внешняя ссылка.

IB>То есть модель знает о DAL, зависит от него и умеет себя загружать. Тебя это не смущает?

Ща скажу заветное слово, будешь хохотаться — IoC.

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


Design Time в пролёте с плоской моделью.

A>> Просто View нам не навязывает структуру DAL.

IB>Структуру DAL навязывает бизнес-логика.

Бизнес-логика и куча разносортных репортов всё же не одно и тоже. Если надо ещё с этого боку данные показать, я ещё один SQL запрос добавлять не собираюсь.

A>>ManufacturerID, OrderID приходят с сервера и по ним получаются из кеша объекты Manufacturer, Order. На них и указывают ссылки. Что же тут непонятного?!

IB>Ты там описывал один объект с перечнем ID-шников, такой объект не нужен ни БД, ни объектной модели — вообще получается какая-то третья промежуточная структура, что и вызывает вопросы.

Не, есть Manufacturer и Order. Есть и кеш Manufacturer, хотя бы Dictionaty<Guid, Manufacturer>, только он для внутреннего использования DAL и снаружи его присутствие никак не видно. Его основная задача даже не кешировать, а обеспечивать для каждого ID всего один объект.

IB>Тебе еще раз рассказать, что любая модель отлично кешируется, вне зависимости от ее представления в памяти?

IB>Прелесть в том, что я в любой момент могу один конкретный запрос, для конкретной View (или чего либо другого) критичный по производительности, или другим параметрам, опустить до уровня БД/сервера, а могу спокойно кешировать копию оригинальных данных и строить нужные структуры в памяти. Как в этом случае будешь изворачиваться ты, со своей "прозрачностью" — я слабо представляю.

Да вобщем-то точно так же. Просто верну полностью заполненный сложный гибридный объект, а не набор простых, частично заполненных.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[39]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 25.01.08 10:17
Оценка:
Здравствуйте, adontz, Вы писали:

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

Ничего там много раз не грузится, забудь.

A>Удобство обращения к данным. Я в объектной модели могу элементарно забиндить значение столбца грида на свойство.

Зашибись, а в плоской что тебе это мешает это сделать?

A>BLL/UI показывать не будет.

Чем он там мешает?

A>А какая разница в каком она виде?

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

A>Её вид и возможность рассогласования абсолютно не связаны.

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

A>Ща скажу заветное слово, будешь хохотаться — IoC.

Не поверишь, я ждал что ты это скажешь.. Так вот IoC — не панацея, он конечно позволит ослабить связность, но от знаний модели о DAL полностью не избавит, тогда как на самом деле это знание не нужно. Теперь самое время поучить другие три буквы — SRP

A>Design Time в пролёте с плоской моделью.

С какого перепугу? Всю жизнь зашибись работало, а теперь в пролете?

A>Бизнес-логика и куча разносортных репортов всё же не одно и тоже. Если надо ещё с этого боку данные показать, я ещё один SQL запрос добавлять не собираюсь.

А что ты собираешься делать?

A>Не, есть Manufacturer и Order.

Не поленился, цитирую: "Потом гружу продажи за май (производитель, товар, количество, покупатель, дата) и виде (ManufacturerID, ProductID, ProductCount, ClientID)."
Зачем такой объект? В базе это все лежит по другому, в OO тоже.

A>Есть и кеш Manufacturer, хотя бы Dictionaty<Guid, Manufacturer>, только он для внутреннего использования DAL и снаружи его присутствие никак не видно. Его основная задача даже не кешировать, а обеспечивать для каждого ID всего один объект.

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

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

Из-за своей "прозрачности" ты не сможешь отличить один случай от другого, ты не сможешь при необходимости явно опустить запрос в DAL, если понадобиться или взять из кеша, если в конкретном случае так эффективнее. Ты вынужден изобретать универсальный механизм или придумывать хитромудрые эвристики чтобы модель догадывалась как в данном случае лучше, и это еще если не брать в рассчет, что источников данных может быть несколько.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[40]: Структура классов модели предметной области
От: adontz Грузия http://adontz.wordpress.com/
Дата: 25.01.08 10:39
Оценка:
Здравствуйте, IB, Вы писали:

A>>Удобство обращения к данным. Я в объектной модели могу элементарно забиндить значение столбца грида на свойство.

IB>Зашибись, а в плоской что тебе это мешает это сделать?

Тем что у меня нет Order.Customer.Name. Надо писать OrderView агрегирующий Order.

A>>BLL/UI показывать не будет.

IB>Чем он там мешает?

просто не нужен.

A>>А какая разница в каком она виде?

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

Ой, ну дело то не в потере, а в оповещении о внешних изменениях.

A>>Её вид и возможность рассогласования абсолютно не связаны.

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

Знаешь, тогда лучше из UI сразу к веб-сервису обращатся, а то в DAL/BLL что-то потеряется.

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


Я думаю лучше вовремя завязать с тремя буквами.

A>>Design Time в пролёте с плоской моделью.

IB>С какого перепугу? Всю жизнь зашибись работало, а теперь в пролете?

К в чему биндить? К ID?

A>>Бизнес-логика и куча разносортных репортов всё же не одно и тоже. Если надо ещё с этого боку данные показать, я ещё один SQL запрос добавлять не собираюсь.

IB>А что ты собираешься делать?

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

IB>То есть, для поддержания ОО модели в адекватном виде, нам нужны еще дополнительные вспомогательные структуры — ЧТД.


ЧТД в каком смысле? Я этого и не отрицал...

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

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

Да нет же
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[40]: Структура классов модели предметной области
От: Ziaw Россия  
Дата: 25.01.08 10:51
Оценка:
Также как по чистой ОО модели, есть вопросы и по плоской модели:

1. Очень редко нужен один плоский объект, как вы их объединяете для пересылки клиенту?

2. Как реализуются с помощью плоской модели colemn-level security?

3. Как обеспечить контроль типов в функциях вида:
  int GetOrdersSomeAggregate(int orderFolderId, int year, int clientId, int goodGroupId);
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[41]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 25.01.08 12:06
Оценка:
Здравствуйте, Ziaw, Вы писали:

Z>1. Очень редко нужен один плоский объект, как вы их объединяете для пересылки клиенту?

В коллекции.. ) На самом деле, довольно редко приходится придумывать какой-нибудь DTO, обычно в таком виде и передается.

Z>2. Как реализуются с помощью плоской модели colemn-level security?

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

Z>3. Как обеспечить контроль типов в функциях вида:

Z>
Z>  int GetOrdersSomeAggregate(int orderFolderId, int year, int clientId, int goodGroupId);
Z>

Ну, если заботит такой контроль типов, то можно сделать GetOrdersSomeAggregate(OrdeFolder, int year, Client, GoodGroup), но я не вижу в этом большего смсла.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[41]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 25.01.08 12:06
Оценка:
Здравствуйте, adontz, Вы писали:

A>Тем что у меня нет Order.Customer.Name.

Да, зато у тебя есть Order.CustomerName, ужастно сложно...
Ты, кстати, в курсе, что, во-первых, для некоторых asp.Net-ых сценариев биндинг вложенных объектов (Customer.Name) не прокатывает, а во вторых, обращение к методам/свойствам вложенных объектов (Order.Customer.Name или, еще лучше, Order.Customer.DeliveryInfo.Address.Name) нарушает еще один очень хороший принцип помогающий избежать излишней связности?

A>просто не нужен.

Я бы не был так категоричен.

A>Ой, ну дело то не в потере, а в оповещении о внешних изменениях.

Типа потерялось, ну и фиг с ним?

A>Знаешь, тогда лучше из UI сразу к веб-сервису обращатся, а то в DAL/BLL что-то потеряется.

DAL и BLL служат для выполнения конкретной задачи (кстати, DAL, для нкоторых оголтелых апологетов ОО, тоже является бесполезной конструкцией), а какую задачу решает твоя ОО модель?

A>Я думаю лучше вовремя завязать с тремя буквами.

Самое худшее — это завязать не вовремя.

A>К в чему биндить? К ID?

Зачем к ID? У тебя есть в объекте все что надо.

A>Вытянуть всё из кеша, кеш заполнить стандартными запросами.

Что мешает сделать так же в плоской модели?

A> Дёргаться только если производительность сильно хромать будет.

Как именно дергаться? Ты себе все подходы "прозрачностью" перекрыл.

A>ЧТД в каком смысле? Я этого и не отрицал...

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

A>Да нет же

А как же?
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[2]: Структура классов модели предметной области
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 03.02.08 10:22
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Тогда можно сделать дополнительное readonly свойство — CustomerName.


Называется это мигрировавший атрибут. Вот, например: http://books.google.com/books?id=37bTEDps2bYC&amp;pg=PA230&amp;lpg=PA230&amp;dq=%22migrated+attributes%22&amp;source=web&amp;ots=lt4Sjb7EP_&amp;sig=wEIlgXdSG85pqjEkkWqGv0EBSgs#PPA230,M1
... << RSDN@Home 1.2.0 alpha rev. 725 on Windows Vista 6.0.6000.0>>
AVK Blog
Re[44]: Структура классов модели предметной области
От: IB Австрия http://rsdn.ru
Дата: 06.02.08 17:41
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>...Видимо не судьба посмотреть на схему которую использует IB.

Ну вы, ребята, даете... У меня еще и основная работа вообще-то есть, помимо написания примеров приложений. Последнюю неделю например, в стэнфорде на конференции просидел, вообще доступа к форумам не было..
Будет время, может напишу, но скоро не ждите.

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

Ну а не проще ли самому попробовать реализовать, и уже потом спрашивать, если что-то не получется или будет неясно? Заодно и опыт наберется..
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re: Структура классов модели предметной области
От: mazurkin http://mazurkin.info
Дата: 07.02.08 08:50
Оценка:
А>Прошу прощения за возможно простые и глупые вопросы, я только недавно начал разбираться в этой теме.

Я тоже нуб в этой области и меня тоже волнует этот вопрос — я даже тут задавал его не так давно.

В книжке "Domain Driven Design: Tackling Complexity in the Heart of Software" by Eric Evans есть глава 6 раздел "Aggregates": насколько я понимаю там как раз описывается эта проблема и рекомендуемый стиль решения — и это решение не совсем вяжется со стилем организации Domain Layer с использованием Hibernate, а именно когда вяжется все и вся.

А ведь раньше спокойно программировал и не заморачивался на такие проблемы
Re[2]: Структура классов модели предметной области
От: mazurkin http://mazurkin.info
Дата: 08.02.08 08:05
Оценка:
Еще есть книжка "Applying Domain Driven Design and Patterns With
Examples in C Sharp and dotNET.chm" — в ней описан указанный пример с
ордерами.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Структура классов модели предметной области
От: MozgC США http://nightcoder.livejournal.com
Дата: 08.02.08 11:05
Оценка:
Здравствуйте, mazurkin, Вы писали:

А на какой странице?
Re[4]: Структура классов модели предметной области
От: mazurkin http://mazurkin.info
Дата: 08.02.08 11:39
Оценка:
MozgC wrote:
> А на какой странице?

Глава 1 — Architecture Styles to Value
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.