大家好,我叫大鸡腿,大家可以关注下我,会持续更新技术文章还有人生感悟,感谢~
前言
这段时间学习了一波ddd,整体下来的感受,现状是业务冗余,业务代码都写在一起很混乱,在复杂业务的时候不方便管理、扩展。
代码设计原则里面就有高内聚,低耦合的原则,ddd其实就是为了实现这想法的。
目的
ddd为了实现高内聚,低耦合的作用,减少每一层的耦合,这样不会互相影响,也方便后续扩展
概念
- 领域:领域是相对于业务领域,或者问题域,范围概念。一个领域会包含多个子域,比如说订单域,会有商品、订单等等子域
- 限界上下文:既然有范围,那么就有边界,领域之间靠context上下文来进行通讯
- 实体、值对象:实体对应PO,值对象,在实体基础上会加上其他属性
- 聚合,聚合根:对实体、值对象会进行聚合,聚合根,可以通过这个访问内部实体的东西,不会直接操作跟内部实体
- 防腐层 ACL:限界上下文处理外界上下文的时候,需要做业务处理
贫血模型
里面只有属性,但是它的校验、属于它方法放在外面。违反单一原则,封装性比较差的
充血模型
里面包括属性,以及对应的方法实现。这样的好处,开闭原则,以后扩展的话在类里头新增方法。放在外面去做的话,其实是修改,应该减少修改的情况
Domain Primitive
在很多业务中,我们面向过程,比如说一个方法(String,String) 参数,他就会有前后顺序,分别代表什么
如果我们把它封装成对象的话,可以减少这样的问题。
原则
- 隐形概念显式化 比如说聚合根,对于一个东西,它有唯一的标识。如果是前者的话,可以是name,phone等等做标识
- 隐式上下文显式化
- 封装多对象
这就是为什么有很多值对象,聚合根,entity,其实是为了封装对应类,以及相关的方法,符合开闭原则
DDD分层
经典ddd分层的就四层:
接口层、应用层、领域层、基础层
接口层:面向接口,controller
Application 属于编排,就是其他层都封装各自小单元类,他们执行的顺序由应用层来处理
应用层:面向用例,就是会管理各个领域的调用关系,比如说校验完->A领域->B领域
领域层:有领域服务,以及对应子域。处理该领域的业务逻辑
基础层:处理数据库、缓存、第三方等等
依赖倒置分层
domain层都是接口,而基础设施层则实现domain接口
有没有想过为啥这么设计?
我们很多框架都强依赖第三方框架,比如说mybatis、mq等等中间件
那么它有什么坏处呢?就是当我换其他组件的时候,会改很多东西
domain层设计成接口的好处,就是具体实现不会强依赖其他组件,随时可以另外实现
domain | 包含内容 | 描述 |
---|---|---|
Repositity | 映射mapper以及扩展,避免强依赖底层 | |
ACL | 防腐层,处理跟外部不一样的东西,比如说协议、api、缓存 |
洋葱架构以及六边形架构,多了适配器
按照个人见解画的分层图
参考博客
阿里淘系有几讲,非常好的介绍以及有案例
个人看法
在一讲的时候真的为啥要封装那么类,封装性,以及测试性比较好。
二讲是针对依赖倒置的情况做解释,也就是避免强依赖其他组件,
三讲Repositity,这里发表个人看法:我觉得我们在系统设计的时候,应该避免过度设计。比如说mybatis plus其实已经实现很多功能,你再封装一个Repositity,很多接口都得重新写。然后一些小项目,很少去改变底层依赖,所以我觉得看菜下饭