领域驱动设计(DDD)的个人见解(一)
为什么要写这篇文章
接触DDD是在上家公司的项目中,是一个从北京回来的同事推荐使用的这个设计模式。当时第一次接触这个概念觉得比较新鲜,就查了文档看这个东西是啥意思,这种设计有啥好处。但看了很多关于相关的文章和博客都云里雾里的,只知道大型的业务适合这种设计模式,小型的就用MVC三层架构就行。在实际实践中,感觉同事也没深刻理解这个设计模式的精髓,项目设计的也没享受到这个设计模式带来的好处。到了我现在这家公司,有很多大型项目的实践,然后能逛内部论坛,有很多文章就是关于DDD的,我再次看了一下。终于有很多重要的收货了,今天做下总结,也分享给迷茫的大家。
强烈推荐一篇文章:
https://mp.weixin.qq.com/s/HMLpjcE0UENUTfMK0Z9n8A
我以下的总结也是根据这篇文章做的总结和读后感吧。为什么选这篇呢,因为这篇这篇通俗易懂而且实践性很强(其他的文章大部分看不懂而且停留在理论,手动笑脸)
DDD的理论和实践
这个参考上面的文章吧,我就不赘述了
DDD理解
下面根据文章中的专栏订阅项目,做一个解读和总结。DDD的总体架构图如下:
对应的项目结构图如下:
-
应用层(application):定义要完成的业务功能,由该层负责协调和编排领域层的原子方法。因此应用层主要负责:
事务控制
查询仓储(注意:只能查询仓储,不能写仓储,写仓储是领域层的能力)
领域事件(domain event)的触发和监听
操作日志
安全认证
这部分是抄的作者的,感觉写的已经很好了,已经把这层的作用写的很详细了。 -
领域层(domain) :围绕领域,定义领域的模型、数据库操作接口、RPC接口(注意是接口,实现不在这里面),领域的业务逻辑(这个没有接口)
-
门面层(facade) :对外暴露的接口
-
门面层实现(facadeImpl) :对外暴露的接口的实现,相当于三层架构的C
-
基础层(infrastructure):调用中间件的接口,以及领域的调用的RPC接口的实现。
-
主程序层(main) :springboot的启动和配置项在这里面。
-
仓库层(repository):相当于DAO层,注意这里只放了领域操作数据库的实现,接口在领域层。
项目间调用
其中带I的表示有接口定义。其中rpc调用就没画了,因为任何地方都可以调用。RPC接口定义在domian层,返回结果是VO。
实现在基础结构层,实现接受的数据为DTO需要,拿到结果得转成VO。
综上所述:
领域设计模式通过分离出领域层,来实现在复杂系统上能够复用领域层代码,各领域间松耦合实现系统扩展性。
facade定义了外部接口,暴露出来供外部调用,repository定义了数据库操作接口,定义的是数据模型的增删改查。
领域相关的逻辑在domain service里面,这是领域业务的基本操作单位其他模块能够复用。facade调用的application是整个业务的逻辑,可能需要操作多个领域,事务啥的都在这个里面,相当于三层架构的service层。facade impl相当于controller做数据准备和结果转换。
注意:
要区分领域模型和数据模型的关系。
- 领域模型建模的关键是看模型能否显性化、清晰的表达业务语义,扩展性是其次。
- 数据模型负责的是数据存储,其要义是扩展性、灵活性、性能。而领域模型负责业务逻辑的实现,其要义是业务语义显性化的表达,以及充分利用OO的特性增加代码的业务表征能力。