【发布时间】:2014-04-03 15:54:39
【问题描述】:
在企业应用架构模式中,Martin Fowler 谈到了组织领域逻辑的两种模式:Domain Model 和 Service Layer。领域模型模式是“纯 OOP”方法,其中模型(可能使用 ORM 从数据库中查找的那些对象)包含业务逻辑(尽管可能只委托给另一个类中的逻辑)。
服务层模式类似于域模型模式,但在它前面有一个薄层,包含可以执行的业务操作。在 MVC 中,控制器主要与服务层交互。我相信大多数设计良好的 MVC Web 应用程序都使用这种模式。
现在,我的问题。 Martin 建议域模型方法是更面向对象的方法,因此更好。根据我的经验,在实践中实施非常困难(参见:不可能)。
以上面第一张图中给出的例子为例。有两个“实体”Contract 和 Product。这些通过映射器持久化到数据库中。在示例中,有一个RecognitionStrategy。 Martin 将委托给包含实际业务逻辑的策略的方法放在实体本身中;客户端使用contract.calculateRecognitions 或contract.recognizedRevenue(someDate) 执行此计算。在实现类似的设计时,我通常将客户端接口写成strategy.calculateRecognitions(contract) 和strategy.recognizedRevenue(contract, someDate)。这使得服务层对于协调策略和合同是必要的。使用的具体策略被注入到服务中。
从设计的角度来看,Martin 的方法肯定更具吸引力,但围绕设置的工作要困难得多:
- 在实例化
Product时传递策略是一种痛苦。您需要通过带有要使用的具体服务的柯里化工厂创建Products,然后在创建实体时将其传递给实体。 - 对数据库访问的细粒度控制较少。根据 ORM 设置,委派给
Product的Contract可能会根据Product执行查询。当我们加载Contract但不打算调用contract.calculateRecognitions()时,在映射器(或ORM)中贪婪地加载Products 可能过于热心了。我的方法为我们提供了更细粒度的控制,因为服务了解数据库抽象层,而实体不应该这样做。
我确信在实践中还有更多我没有在这里列举的痛点。
Martin 的方法有哪些具体优势可以说服我使用纯数据模型模式?
【问题讨论】:
标签: design-patterns service-layer architectural-patterns anemic-domain-model