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