Могут ли объекты Persistance-Ignorant реализовать ленивую загрузку?

12

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

а) Я предполагаю, что это означает, что код, который связывается с нижними уровнями (то есть уровнями персистентности), живет вне модели предметной области в других классах ( OC ) уровня бизнес-логики?

б) Если мое предположение в соответствии с а) верно, то ДО , скажем Customer, никогда не содержит такие методы, как GetCustomersили GetCustomerByID?

c) Если мои предположения по пунктам a) и b) верны и предполагается, что Customerобъект домена использует ленивую загрузку для некоторых своих свойств, то в какой-то момент Customerвнутренняя логика должна связаться с OC , который, в свою очередь, получает отложенные данные. Но если Customerнеобходимо связаться с OC для получения отложенных данных, то мы не можем утверждать, что доменные объекты не содержат логики, связанной с постоянством ?!

Спасибо

ОТВЕТИТЬ НА Jkohlhepp

1) Я полагаю, OrderProviderи CustomerProviderклассы содержатся в слое бизнес-логики?

2) Я понял из вашего ответа, что мои предположения по пункту b) верны?

3)

... Я бы проверил, заполнено ли какое-то поле частных заказов или оно пустое. Если это ноль ...

Но, насколько я могу судить, как только код домена должен проверить, было ли orderзаполнено приватное поле, и, если это не так, связываясь с OrderProvider, мы уже нарушаем принцип PI ?!

user1483278
источник

Ответы:

4

Я полагаю, что вы правы в своих предположениях A и B относительно постоянного невежества.

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

Я склонен реализовывать постоянное невежество, используя следующие классы:

  • Доменные классы - например, Клиент
  • Классы провайдера / репозитория - например, CustomerProvider
  • Общие классы запросов к базе данных - например, DatabaseQuery

Класс DatabaseQuery будет отвечать за использование драйвера базы данных для запроса базы данных и объединения полученных данных в общий набор результатов, такой как DataTable. CustomerProvider будет нести ответственность за использование класса DatabaseQuery для выполнения SQL для базы данных и использования результатов этого SQL для сборки экземпляров Customer. Заказчиком будет «чистый» объект домена, содержащий данные и логику, относящиеся к клиентам.

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

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

На мой взгляд, необходимость обращения Заказчика в OrderProvider не нарушает ПИ. Клиент до сих пор не знает, как он получает заказы. Он просто знает, что получает их от OrderProvider. Могут быть и другие причины, чтобы отделить Customer от OrderProvider, но я не думаю, что здесь есть проблема с PI.

Это предполагает, что вы делаете невежество постоянным вручную. Если вы используете среду ORM, такую ​​как Entity Framework или Hibernate, то эти платформы обычно имеют функции для автоматической поддержки отложенной загрузки.

RationalGeek
источник
привет, если вы найдете время - я отредактировал свой пост в ответ на ваш ответ
user1483278
1
@ user1483278 Я отредактировал свой ответ, чтобы, надеюсь, ответить на эти вопросы.
RationalGeek
Что означает ПИ?
Кугель,
Постоянство Невежество
RationalGeek
2

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

Эрик Дитрих
источник