Как использовать объектно-ориентированное программирование с Hibernate?

При использовании инструментов ORM, таких как Hibernate, я нашел выгодным оставить всю бизнес-логику из своих бизнес-объектов и вместо этого сохранить ее на уровне обслуживания. Уровень обслуживания создает POJO бизнес-объекта, управляет ими и использует DAO для их сохранения. Но разве это не делает шаг назад от объектно-ориентированного характера Java?

Мой стек включает Spring с Hibernate для DI, транзакций и настойчивости. Мои DAO вводятся в мой сервисный уровень, а не в POJO.

Недавно я прочитал документ Mark Fowler учетных записей для создания гибких систем учета. Я считаю, что это было написано до увлечения Spring/Hibernate/DI/ORM. Он описывает объекты, которые содержат бизнес-логику. Эти объекты используют наследование и композицию элегантными способами, которые имеют смысл.

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

В документе шаблонов учета Мартина Фаулера он описывает базовый класс AccountingEvent. Этот класс может иметь подклассы, такие как UsageEvent и InstallationEvent.

UsageEvent:

  • UsageEvent происходит, когда считыватель счетчиков записывает ваше потребление электроэнергии.
  • Клиент ServiceAgreement просматривается
  • Соответствующие PostingRule находятся в соглашении об обслуживании для этого типа события и за этот конкретный период времени. Правила и тарифы могут меняться со временем, поэтому для любого типа события существует несколько PostingRule.
  • UsageEvent и PostingRule определяют, какие действия должны выполняться, например, создание одного или нескольких объектов AccountingEntry.
  • Создан AccountingEntry для выставления счета за использование с логикой, содержащейся в PostingRule. Это может быть так же просто, как rate * usage, но, вероятно, намного сложнее, исходя из времени суток, уровней обязательств (крупные компании могут получать скидки), домохозяйств с низким доходом и т.д.
  • Дополнительные AccountingEntry создаются для выставления счетов за налоги, предоставления кредитов и т.д.

InstallationEvent:

  • InstallationEvent происходит, когда техник активирует питание здания.
  • Соглашение об обслуживании и PostingRule найдены
  • Созданы соответствующие AccountingEntry
  • Используются разные логики и правила, чем в UsageEvent

Дело в том, что существует много разных типов AccountingEvent и PostingRule s, каждый из которых точно знает, что делать для конкретной ситуации. Эти объекты легко взаимозаменяемы с использованием интерфейсов. Я могу ударить все, просто выдав команду someAccountingEvent.process().

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

Ответ 1

Возможно, вы говорите о том, что называется Anemic domain model". Я ранее ответил на вопрос по теме, который указывает на статью в блоге о том, как вводить службы в экземпляры модели, которые Hibernate он извлекает.

Spring и модель анемичного домена

Ссылка на статью в блоге Разработка домена с помощью Spring и спящего режима

Ответ 2

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