Структура классов модели предметной области
От: Аноним  
Дата: 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: Структура классов модели предметной области
От: Кирилл Лебедев Россия 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[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[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]: Структура классов модели предметной области
От: Кирилл Лебедев Россия 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[3]: Структура классов модели предметной области
От: Trean Беларусь http://axamit.com/
Дата: 15.01.08 14:04
Оценка: +1
Здравствуйте, KolanT, Вы писали:

KT>

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

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

Речь как я понимаю ведется о том, чтобы хранить объектную ссылку на объект в другом объекте или хранить pk этого объекта. Лучше конечно, ссылку, так правильнее с точки зрения ОО дизайна, так как в этом случае нет привязки к тому, как хранятся и идентифицируются объекты в хранилище (это не обязательно РСУБД и PK).
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: Структура классов модели предметной области
От: 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[4]: Структура классов модели предметной области
От: Аноним  
Дата: 16.01.08 02:07
Оценка:
Здравствуйте, Кирилл Лебедев, Вы писали:

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


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

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


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

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


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


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


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

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

Доменная модель, как и вся архитектура должна решать одну задачу — исполнить требования пользователя в максимально меньшие сроки с минимальным возможностей ошибок. Догматичность в архитектуре — вредна. Флейм когда использовать а когда не использовать DTO и что такое "подмена целей средствами", начинать не буду. Благо через поиск можно все найти.
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>Доменная модель, как и вся архитектура должна решать одну задачу — исполнить требования пользователя в максимально меньшие сроки с минимальным возможностей ошибок.

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