对于领域模型的学习在12年的多篇博文里面已经谈到过,今天再翻看《领域驱动设计》一书的时候,发现对于规格即Specification模式本身在前面学习的时候没有很好的理解。
对于Specification模式是在第九章讲解将隐式概念转变为显式概念的时候讲到的,首先为何会单独剥离规格类,书里面的最重要解释就是对于业务规则通常不适合做为entity或value object本身的职责,而且规则的变化和组合也会掩盖领域对象的基本含义。但是如果将规则移出领域层,那么结果会更加糟糕,因为领域代码本身就不再很好的表达业务模型了。
对于Specification模式的主要应用场景书里面谈到三点,即:
如果从以上几点来看的话,对于规格模式可以更多的看做是对业务实现过程中业务规则的单独剥离,放到独立的规格类来实现,主要就是处理业务规则。在谈到这里的时候我们再回顾下领域模型中的几个特定对象:
如果基于这些核心对象来看,需要增加一些对整个领域模型和模式使用的一些分析。
对于最简单的业务对象的业务操作,比如就一个单表用户信息的维护,这种场景下Repository对象下的实体CRUD方法已经够用,但是还是要通过Service对象进一步封装再暴露为服务接口。只有对于复杂对象的时候才启用聚合和工厂模式,这从减轻架构的复杂性上是可以的。
对于Service对象中的每一个方法最好都是对应明确的业务方法,这些业务方法往往是对应到业务系统前台具体的业务功能或业务操作的。如一个转账操作可以是service层的一个方法,但是在转账操作的实现过程中需要判断用户账户是否有效,用户是否有欠款,那么这些就是业务规则。
对于业务规则不需要暴露为Service对象中的具体方法,在不考虑Specification模式的时候可以将具体的业务规则直接写到Service方法里面,但是可以看到会导致Service对象变重,而对于Service对象更多应该只是下层对象的方法调用和方法组合。因此才会出现将业务规则单独抽取为独立的方法,同时新增加一个规则类类存储这些规则和方法。
在这样处理后,整个逻辑和思路和常见的SOA架构方法论就能够更好的对应和映射,即:实体和仓储类:更多的是承载对象的CRUD数据操作,不承载过多的业务规则;规格类:承载业务规则,是在实体和仓储类外的业务规则和逻辑校验实现等。而对于Service类则变成了对上面谈到的两类对象中方法的调用和组合,本身并没有太多的业务和规则实现。如果按照这种方法来实现,那么Service中的方法更多都可以转化为后期的BPEL服务编排方式来实现。
疑问点1:规则类是否可以直接访问DAO层,在书里面是可以的,即这部分规则实现是不走实体和仓储类的。
疑问点2:工厂类是否只是实现了实体构造和仓储类分离,对于单实体是否可以取消工厂类