一文了解DDD分层架构演进
1.3 分层架构演进
1.3.1 传统四层架构
将领域模型和业务逻辑分离出来,并减少对基础设施、用户界面甚至应用层逻辑的依赖,因为它们不属业务逻辑。将一个夏杂的系统分为不同的层,每层都应该具有良好的内聚性,并且只依赖于比其自身更低的层。
传统分层架构的基础设施层位于底层,持久化和消息机制便位于该层。
这里的消息包含
- MQ消息
- SMTP
- 文本消息(SMS)
可将基础设施层中所有组件看作应用程序的低层服务,较高层与该层发生耦合以复用技术基础设施。即便如此,依然应避免核心的领域模型对象与基础设施层直接耦合
。
1.3.2 改良版四层架构
传统架构的缺陷
DDD初创开发团队发现,将基础设施层放在最底层存在缺点,比如此时领域层中的一些技术实现就很困难:
- 违背分层架构的基本原则
- 难以编写测试用例
何解?
使用依赖反转设计原则:低层服务(如基础设施层)应依赖高层组件(比如用户界面层、应用层和领域层)所提供的接口。
应用依赖反转原则
- 依赖反转原则后的分层方式:基础设施层在最上方,可实现所有其他层中定义的接口
依赖反转原则真的可以支持所有层吗?
有人认为依赖反转原则中只存在两层:最上方和最下方,上层实现下层定义的抽象接口。因此上图的基础设施层将位于最上方,而用户接口层、应用层和领域层应作同层且都位于下方。对此大家可保留自己意见。
2 各层职责
2.1 用户接口层
一般包括用户接口、Web 服务等。
只处理用户显示和用户请求,不应包含领域或业务逻辑。
有人认为,既然用户接口需验证用户输入,就无可避免应该包含业务逻辑。事实上,用户接口所进行的验证和对领域模型的验证不同:对那些粗制滥造且只面向领域模型的验证行为,应该予以限制。
如果用户接口使用了领域模型中的对象,那么此时领域对象仅限于数据渲染展现。在采用这种方式时,可使用展现模型对用户接口与领域对象进行解耦。
由于用户可能是人,也可能是其他系统,有时用户接口层将采用开放主机服务的方式向外提供API。
用户接口层是应用层的直接用户。
用户接口层在于前后端调用的适配。若你的微服务要提供服务给很多外部应用,而对每个外部应用的入参出参都不同,你不可能开发一堆一对一的应用服务,这时Facade接口就起到了很好的作用,包括DO和DTO对象的组装和转换。
2.2 应用层
主要包含应用服务,理论上不应有业务规则或逻辑,而主要是面向用例和流程相关的操作。
- 应用层位于领域层之上,因为领域层包含多个聚合,所以它可协调多个聚合服务和领域对象完成服务编排和组合,协作完成业务。
- 应用层也是微服务间的交互通道,它可调用其它微服务,完成微服务间的服务组合和编排。
开发设计时,不要将本该放在领域层的业务逻辑放到应用层。因为庞大的应用层会使领域模型失焦,时间一长,微服务就会退化为MVC架构,导致业务逻辑混乱。
应用服务是在应用层,负责
- 服务的组合、编排、转发、转换和传递,处理业务用例的执行顺序以及结果的拼装,以粗粒度服务通过API网关发布到前端
- 安全认证
- 权限校验
- 事务控制
- 发送或订阅领域事件
2.3 领域层
主要包含聚合根、实体、值对象、领域服务等领域模型中的领域对象。
实现核心业务逻辑,通过各种校验保证业务正确性。领域层主要体现领域模型的业务能力,它用来表达业务概念、业务状态和业务规则。
领域模型的业务逻辑主要由实体和领域服务实现:
- 实体采用充血模型 实现所有与之相关的业务功能。
实体和领域服务在实现业务逻辑上不是同级,当领域中的某些功能,单一实体或值对象无法实现,就会用到领域服务,它可组合聚合内的多个实体或值对象,实现复杂业务逻辑。
2.4 基础层
为其它各层提供通用技术基础服务:
- 三方工具
- 驱动
- MQ
- API网关
- 文件
- 缓存
- DB
最常用的
基础层包含基础服务,它采用依赖反转,封装基础资源服务,实现应用层、领域层与基础层解耦。
MVC架构由于上层应用对DB强耦合,很多公司在架构演进最怕换DB,一旦更换,可能需重写一堆代码。
但采用依赖反转,应用层即可通过解耦保持独立核心业务逻辑。当DB变更,只需更换DB基础服务。
本文由mdnice多平台发布