如何使用Hibernate进行面向对象编程?

时间:2011-03-30 06:54:30

标签: java oop hibernate spring orm

在使用Hibernate之类的ORM工具时,我发现将所有业务逻辑保留在业务对象之外并将其保留在服务层中是有利的。服务层创建业务对象POJO,操作它们,并使用DAO来保存它们。但是,这不是从Java的面向对象性质向后退一步吗?

我的堆栈包括用于DI,事务和持久性的Spring with Hibernate。我的DAO被注入我的服务层,而不是注入任何POJO。

最近,我阅读了Martin Fowler关于建立灵活会计系统的accounting patterns文件。我相信它是在Spring / Hibernate / DI / ORM热潮之前编写的。它描述了包含业务逻辑的对象。这些对象以优雅的方式使用继承和组合。

通过将逻辑放入类中,可以将其划分为仅与一个特定场景相关的整齐单元。在我的服务层中,我最终拥有许多不同的方法,每种方法都处理不同的场景。但它远非面向对象。

在Martin Fowler的会计模式文档中,他描述了AccountingEvent的基类。此类可能包含UsageEventInstallationEvent等子类。

UsageEvent

    当仪表读卡器记录您的用电量时,会发生
  • UsageEvent
  • 查找客户的ServiceAgreement
  • 在此类事件的服务协议中以及此特定时间段内找到相应的PostingRule。规则和费率可能会随着时间的推移而变化,因此对于任何给定类型的事件都存在多个PostingRule
  • UsageEventPostingRule确定需要执行的操作,例如创建一个或多个AccountingEntry个对象。
  • 创建AccountingEntry以使用PostingRule中包含的逻辑来计费。这可能就像rate * usage一样简单,但根据一天中的时间,承诺水平(大企业可能获得折扣),低收入家庭等可能要复杂得多。
  • 创建额外的AccountingEntry以计税,提供积分等。

InstallationEvent

    当技术人员激活建筑物的电源时,会发生
  • InstallationEvent
  • 找到服务协议和PostingRule
  • 创建了适当的AccountingEntry
  • 使用了与UsageEvent
  • 不同的逻辑和规则

关键是有许多不同类型的AccountingEventPostingRule,每个都知道如何处理特定情况。这些对象可以使用接口轻松互换。只需发出命令someAccountingEvent.process()即可完成所有操作。

当我必须在服务层中创建和保存实体时,我不清楚如何获得一些优雅的最佳方法。我不想将我的DAO注入到我的POJO中,这会为它们添加额外的依赖关系,并可能使它们成为更重的重量对象。但是,如何在我可以注入DAO的服务层中最好地建模这样的东西?

2 个答案:

答案 0 :(得分:4)

你可能在谈论所谓的“Anaemic domain model”。我之前回答了一个关于该主题的问题,该问题指向一篇关于如何将服务注入到Hibernate检索的模型实例中的博客文章。

Spring and the Anaemic Domain Model

引用的博客文章是Domain Driven Design with Spring and Hibernate

答案 1 :(得分:1)

有效的问题,我不知道解决方案。但有一种想法:面向对象的设计不是目标,它是达到目的的手段。如果在您的架构中最容易出现贫血域模型,那么也许您应该使用它;游泳框架的流动通常会让事情变得更加艰难。也就是说,在可能的情况下争取优雅,面向对象的解决方案始终是健康的。在这种情况下,在阅读James Blewitt's blog关于主题后,可能会有一些可行的新方法。