🏆 原文:11|代码实现(中):怎样创建领域对象、实现领域逻辑?
DDD 强调,每个类和方法的命名都应该尽量直观地反映领域知识,与统一语言保持一致。这种做法也是 DDD 的一个模式,叫做 “Intention-Revealing Interfaces”,可以译作表意接口。
领域服务(domain service)
如果一个逻辑需要和领域专家讨论才能确认的,就是领域逻辑;
比如说,Validator 中的各种校验规则,都是与领域专家澄清的,所以属于领域逻辑。
这里的各种 Validator 也是 DDD 中的一个模式,叫做领域服务(domain service)。这个模式的思路是这样的:按照面向对象的做法,领域逻辑本来最好放到领域对象中去,不过有些逻辑又不适合放到领域对象,这时,干脆放到一些只有方法,没有状态的类里面。给这些类取个名字,就叫领域服务吧。
工厂(Factory)模式
DDD 认为,领域对象的创建逻辑也是领域层的一部分。 DDD 认为用于校验的领域逻辑也属于创建过程的一部分。
使用 Builder 模式消除 DTO
- 将 DTO 中的属性全部转移到 Builder 中
- Builder 可以直接创建领域对象
- 如果 Builder 还依赖 Validator,可以使用 BuilderFactory 来创建 Builder
分包策略
- 按照类的“性质”来分:OrgRepository 和 EmpRepository 在性质上都属于 Repository,所以把它们放在同一个包,至于它们之间有没有调用关系,并不重要。
- 按照耦合关系来分:OrgRepository 中方法的参数用到了 Org 类,说明这两个类型之间有耦合关系,所以把它们放在同一个包,尽管它们的性质不一样,一个是实体,一个是仓库。
这两种方式没有绝对的对错,需要进行权衡。比如说,分层架构其实就是按性质来分的。应用层的应用服务,之所以在同一个包里面,并不是因为他们之间有耦合关系,而是因为他们都是领域对象的“门面”。
我们在分层架构中采用按性质分包的方式,是因为,将领域逻辑与其非领域逻辑分离,以及将技术相关和无关两部分分离,这两个“关注点分离”的好处实在太大,大过了破坏“松耦合高内聚”原则的代价。
在每个层次内部,建议尽量按照耦合性分包。这是由于排除上述两个“关注点分离”以后,“松耦合高内聚”的好处就体现出来了。