При использовании инструментов ORM, таких как Hibernate, я обнаружил, что выгодно не включать всю бизнес-логику в мои бизнес-объекты, а вместо этого держать ее на уровне сервисов.Сервисный уровень создает POJO бизнес-объекта, манипулирует ими и использует DAO для их сохранения.Но разве это не делает шаг назад от объектно-ориентированной природы Java?
Мой стек включает Spring с Hibernate для DI, транзакций и персистентности.Мои DAO внедряются в мой сервисный уровень, а не в какие-либо POJO.
Недавно я прочитал документ Мартина Фаулера о построении гибких систем учета.Я считаю, что это было написано до увлечения Spring / Hibernate / DI / ORM.Он описывает объекты, которые содержат бизнес-логику.Эти объекты используют наследование и композицию изящными способами, которые имеют смысл.
Поместив логику в классы, ее можно разбить на аккуратные единицы, которые относятся только к одному конкретному сценарию.На моем уровне обслуживания у меня много разных методов, каждый из которых имеет свой сценарий.Но это далеко от объектно-ориентированного.
В документе бухгалтерских шаблонов Мартина Фаулера он описывает базовый класс AccountingEvent
.Этот класс может иметь подклассы, такие как UsageEvent
и InstallationEvent
.
UsageEvent
:
UsageEvent
происходит, когда считыватель регистрирует ваше потребление электроэнергии - Просматривается
ServiceAgreement
клиента - Соответствующие
PostingRule
s найдены в сервисном соглашении для этого типа события и для этого конкретного периода времени.Правила и тарифы могут меняться со временем, поэтому для любого конкретного типа события существует несколько PostingRule
. UsageEvent
и PostingRule
определяют, какие действия необходимо выполнить, например, создать одно илибольше AccountingEntry
объектов. AccountingEntry
создается для выставления счета за использование с логикой, содержащейся в PostingRule
.Это может быть так же просто, как rate * usage
, но, вероятно, гораздо сложнее, в зависимости от времени суток, уровня обязательств (крупные компании могут получать скидки), домохозяйств с низким доходом и т. Д. - Дополнительно
AccountingEntry
ссоздаются для выставления счетов за налоги, предоставления кредитов и т. д.
InstallationEvent
:
InstallationEvent
происходит, когда техник активирует электричество в здании. - Соглашение на обслуживание и
PostingRule
s найдено - Соответствующие
AccountingEntry
s созданы - Используется гораздо другая логика и правила, чем в
UsageEvent
Дело в том, что существует много разных типов AccountingEvent
s и PostingRule
s, каждый из которых точно знает, что делать для конкретной ситуации.Эти объекты легко взаимозаменяемы с помощью интерфейсов.Я могу справиться со всем, просто введя команду someAccountingEvent.process()
.
Я не уверен, как лучше вернуть часть этой элегантности, когда мне нужно создавать и сохранять объекты на уровне сервиса.Я не хочу вставлять свои DAO в мои POJO, которые добавили бы к ним дополнительные зависимости и потенциально сделали бы их гораздо более тяжелыми объектами веса.Но как мне лучше всего смоделировать что-то подобное в моем слое обслуживания, где я могу внедрять DAO?