【DDD】基于DDD的分层设计

参考:https://insights.thoughtworks.cn/ddd-in-distributed-system/  在分布式系统中使用DDD


DDD 的四层架构: 接入层、应用层(Application Servier)、领域层(Domain Service)、基础设施层

- 接入层:在复杂度不高的情况下,我们往往把接入层和应用层合并部署,

  • 关心视图和对外的服务,Restful、页面渲染、websocket、XMPP 连接等
  • 如果没有多种接入方式,可以和应用层合并
  • 对应到分布式系统中的网关、BFF、前台等概念
  • 只产生接入异常,例如数据校验,对应 HTTP 状态码 400、415 等
  • 一个应用可以有多个接入层
  • 接入层做和业务规则无关的 bean validation 验证
  • 准单体系统下,按照连接方式分包

- 应用层:  

  • 关心处理完一个完整的业务
  • 该层只负责业务编排,对象转换,实际业务逻辑由领域层完成
  • 不关心请求从何处来,但是关心谁来、做什么、有没有权限做
  • 集成不同的领域服务解决问题
  • 最终一致性(最终一致性对业务有侵入)事务放到这层
  • 对应到分布式系统中的中台等概念
  • 方法级别的功能权限控制放到这层
  • 只产应用异常,对应 HTTP 状态码 403、401
  • 准单体系统下,按照应用划分模块

- 领域层:  

  • 不关心场景,关心模型完整性和业务规则
  • 不关心谁来,不关心场景完整的业务,关心当前上下文的业务完整
  • 强一致性事务放到这层,聚合的事务是 "理所当然的"
  • 对应到分布式系统中的 domain service、后台等概念
  • 领域层做业务规则验证
  • 产生业务规则异常,例如用户退款条件不满足,对应状态码 412、419 等
  • 数据权限放到这层(比如只允许删除自己创建的商品),因为数据权限涉及业务规则
  • 准单体系统下按照上下文分包,上下文之间调用必须走领域 domain service,目的就是解耦
  • 上下文中分聚合,聚合根要足够小,只允许聚合根拥有对应的 domain service
  • 根据业务情况,参考反范式理论,跨上下文使用值对象做必要的数据冗余

- 基础设施层:技术设施层并不是指 MySQL、Redis 等外部组件,而是外部组件的适配器,Hibernate、Mybatis、Redis Template 等,因此在 DDD 中适配器模式被多次提到,基础设施层往往不能单独存在,还是要依附于领域层。技术设施层的适配器还包括了外部系统的适配  

  • 关心存储、通知、第三方系统等外部设施(防腐层隔离)
  • 如果使用自动化的 ORM,这层可以在一定程度上省略
  • 基础设施异常,应丢出内部异常,对应状态码 500
  • 准单体系统下按照 adapter 分包
  • 基础设施的权限由配置到应用的凭证控制,例如数据库、对象存储的凭证,技术设施层不涉及用户的权限
原文地址:https://www.cnblogs.com/clarino/p/15509483.html