При использовании инструментов 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?