在企业应用程序架构模式中,Martin Fowler讨论了组织域逻辑的两种模式:域模型和服务层.域模型模式是"纯OOP"方法,其中模型(可能使用ORM从数据库中查找的那些对象)包含业务逻辑(尽管可能仅委托给另一个类中的逻辑).
服务层模式类似于域模型模式,但前面有一个薄层,包含可以执行的业务操作.在MVC中,控制器主要与服务层交互.我相信大多数精心设计的MVC Web应用程序都使用这种模式.
现在,我的问题.Martin建议域模型方法是面向对象的方法,因此更好.根据我的经验,在实践中实施非常困难(见:不可能).
以上面第一个图中给出的例子为例.有两个"实体" Contract
和Product
.这些使用映射器持久保存到数据库.在这个例子中,有一个RecognitionStrategy
.Martin在实体本身中提出了委托此策略的方法,该策略包含实际的业务逻辑; 客户端使用contract.calculateRecognitions
或执行此计算contract.recognizedRevenue(someDate)
.在实现类似设计时,我通常将客户端接口编写为strategy.calculateRecognitions(contract)
和strategy.recognizedRevenue(contract, someDate)
.这使得服务层成为协调战略和合同所必需的.使用的具体策略注入服务.
从设计的角度来看,Martin的方法肯定更具吸引力,但围绕设置的工作要困难得多:
在实例化a时传递策略Product
是一种痛苦.您需要Product
通过一个使用具体服务的工厂创建s,然后在创建它时将其传递给实体.
对数据库访问的细粒度控制较少.根据ORM设置,Contract
委托Product
可以执行查询Product
.Product
当我们加载a Contract
但不打算调用时,在mapper(或ORM)中贪婪地加载s可能过于热心contract.calculateRecognitions()
.我的方法为我们提供了更细粒度的控制,因为服务具有数据库抽象层的知识,而实体则不应该知道.
我确信在实践中还有更多的痛点,我在这里没有列举.
Martin的方法有哪些具体优势可能说服我使用纯数据模型模式?