简体   繁体   English

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

[英]How to use object oriented programming with Hibernate?

While using ORM tools such as Hibernate, I've found it is advantageous to keep all business logic out of my business objects and instead keep it in a service layer. 在使用Hibernate等ORM工具时,我发现将所有业务逻辑从业务对象中保留下来并将其保留在服务层中是有利的。 The service layer creates the business object POJOs, manipulates them, and uses DAOs to save them. 服务层创建业务对象POJO,操作它们,并使用DAO来保存它们。 But isn't this in a way taking a step backwards from the object oriented nature of Java? 但是,这不是从Java的面向对象性质向后退一步吗?

My stack includes Spring with Hibernate for DI, transactions, and persistence. 我的堆栈包括用于DI,事务和持久性的Spring with Hibernate。 My DAOs are injected into my service layer, not into any POJOs. 我的DAO被注入我的服务层,而不是注入任何POJO。

Recently I read Martin Fowler's accounting patterns document on building flexible accounting systems. 最近我读了Martin Fowler关于建立灵活会计系统的会计模式文档。 I believe it was written before the Spring/Hibernate/DI/ORM craze. 我相信它是在Spring / Hibernate / DI / ORM热潮之前编写的。 It describes objects that contain business logic. 它描述了包含业务逻辑的对象。 These objects use inheritance and composition in elegant ways that make sense. 这些对象以优雅的方式使用继承和组合。

By putting the logic into classes, it can be partitioned into neat units that only pertain to one specific scenario. 通过将逻辑放入类中,可以将其划分为仅与一个特定场景相关的整齐单元。 In my service layer I end up having lots of different methods, each which deals with a different scenario. 在我的服务层中,我最终拥有许多不同的方法,每种方法都处理不同的场景。 But it is far from object oriented. 但它远非面向对象。

In Martin Fowler's accounting patterns document, he describes a base class of AccountingEvent . 在Martin Fowler的会计模式文档中,他描述了AccountingEvent的基类。 This class might have subclasses such as UsageEvent and InstallationEvent . 此类可能具有子类,例如UsageEventInstallationEvent

UsageEvent : UsageEvent

  • UsageEvent occurs when a meter reader records your electricity usage 当仪表读卡器记录您的用电量时,就会发生UsageEvent
  • Customer's ServiceAgreement is looked up 查询客户的ServiceAgreement
  • The appropriate PostingRule s are found in the service agreement for this type of event and for this particular time period. 适当的PostingRule可以在此类事件的服务协议中找到,也可以在此特定时间段内找到。 Rules and rates can change over time, so multiple PostingRule s exist for any given type of event. 规则和费率可能会随着时间的推移而变化,因此对于任何给定类型的事件都存在多个PostingRule
  • The UsageEvent and PostingRule s determine what actions need to take place, such as creating one or more AccountingEntry objects. UsageEventPostingRule确定需要执行的操作,例如创建一个或多个AccountingEntry对象。
  • An AccountingEntry is created to bill for the usage with logic contained in the PostingRule . 创建AccountingEntry以使用PostingRule包含的逻辑来PostingRule This could be as simple as rate * usage , but is probably much more complex, based on time of day, commitment levels (big businesses might get discounts), low income households, etc. 这可能就像rate * usage一样简单,但可能会更复杂,基于一天中的时间,承诺水平(大企业可能获得折扣),低收入家庭等。
  • Additional AccountingEntry s are created to bill for taxes, provide credits, etc. 创建额外的AccountingEntry以计税,提供信用等。

InstallationEvent : InstallationEvent

  • InstallationEvent occurs when a technician activates power to a building. 当技术人员激活建筑物的电源时,就会发生InstallationEvent
  • Service agreement and PostingRule s are found 找到服务协议和PostingRule
  • Appropriate AccountingEntry s are created 创建适当的AccountingEntry
  • Much different logic and rules are used than in UsageEvent UsageEvent中使用的逻辑和规则有很多不同

The point is that there are many different types of AccountingEvent s and PostingRule s, each of which knows precisely what to do for a specific situation. 重点是有许多不同类型的AccountingEventPostingRule ,每个类型都精确地知道如何处理特定情况。 These objects are easily interchangeable using interfaces. 这些对象可以使用接口轻松互换。 I can kick of everything by simply issuing the command someAccountingEvent.process() . 我只需发出命令someAccountingEvent.process()

I'm unclear on the best way to get some of this elegance back when I have to create and save entities within the service layer. 当我必须在服务层中创建和保存实体时,我不清楚如何获得一些优雅的最佳方法。 I don't want to inject my DAOs into my POJOs, which would add extra dependencies to them and potentially make them much heavier weight objects. 我不想将我的DAO注入到我的POJO中,这会为它们添加额外的依赖关系,并可能使它们成为更重的重量对象。 But how would I best model something like this in my service layer where I can inject DAOs? 但是,如何在我可以注入DAO的服务层中最好地建模这样的东西?

You might be talking about what's referred to as an " Anaemic domain model ". 你可能在谈论什么被称为“ 贫血领域模型 ”。 I have previously answered a question on the topic which points to a blog article about how to inject services into model instances which Hibernate it retrieving. 我之前回答了一个关于该主题的问题,该问题指向一篇关于如何将服务注入到Hibernate检索的模型实例中的博客文章。

Spring and the Anaemic Domain Model 春天和贫血领域模型

The referenced blog article is Domain Driven Design with Spring and Hibernate 引用的博客文章是Spring驱动设计和Spring和Hibernate

Valid question, and I don't know the solution. 有效的问题,我不知道解决方案。 One thought though: Object-oriented design is not the goal, it is a means to an end. 但有一种想法:面向对象的设计不是目标,它是达到目的的手段。 If it's easiest to have an anaemic domain model within your architecture, then maybe you should use it; 如果在您的架构中最容易出现贫血域模型,那么也许您应该使用它; swimming against the flow of your frameworks will usually make things a lot harder. 游泳框架的流动通常会让事情变得更加艰难。 That said, it is always healthy to strive for elegant, more object-oriented solutions where possible. 也就是说,在可能的情况下争取优雅,面向对象的解决方案始终是健康的。 In this case, after reading James Blewitt's blog about the subject, there might be some viable new approaches. 在这种情况下,在阅读James Blewitt关于该主题的博客后,可能会有一些可行的新方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM