看得见摸得着的DDD领域驱动设计

七八年前大家就开始流行聊DDD了,但那时很少有人能说得明白。现在DDD逐渐变成了能听得懂、说得清、看得见、摸得着的方法。今天咱们就来聊一聊。

对复杂的理解

DDD领域驱动设计是软件复杂性应对之道。这个复杂性怎么理解呢?

fa1463a434d61f90e3947aab0bea05fb.png

Jurgen Appelo从理解力与预测能力两个维度分析了复杂系统理论。理解力的复杂度体现在规模和结构上。预测能力的复杂度体现在变化上。从对应的手段上,规模复杂度可以通过分解分而治之;结构上的复杂度可以通过领域编程模型等结构来清晰;对于变化可以通过抽象来提高扩展性。其实扩展性问题总体而言无非两点:预测变化和封装变化。规模复杂度分解上领域驱动设计有4重边界。

领域驱动设计的四重边界

7dc3d25c8be17f137f6dbe094afed93c.png

根据上图所示,我们通过四重来进行架构设计:

分而治之:DDD通过规划四重边界,把领域知识做了合理的固化和分层。业务有核心领域和支撑域、业务域中又拆分成多个限界上下文,一个限界上下文中又根据领域知识核心与否进行分层,领域层中按照多个业务(子域)的强相关性进行聚合成一个子域。

【第一重边界】确定项目的愿景与目标,确定问题空间,确定核心子领域、通用子领域(多个子领域可以复用)、支撑子领域(额外功能,如数据统计、导出报表)

【第二重边界】解决方案空间里的限界上下文就是一道进程隔离层面的物理边界

【第三重边界】每个限界上下文内,使用分层架构划分为:接口层、领域层、应用层、基础设施层之间的最小隔离

【第四重边界】领域层里为了保证各个领域的完整性和一致性,引入聚合的设计作为隔离领域模型的最小单元

领域编程模型

对结构复杂度的模型,近来比较推崇的是菱形对称架构。

菱形对称架构(Rhombic Symmetric Architecture) 主要针对领域层次的架构,借鉴了六边形架构、分层架构、整洁架构的知识,并结合了领域驱动设计的元模型,使其能够更好地运用到限界上下文的架构设计中。

056683862a68146895cf403b7843b7e9.png

菱形对称架构去掉了应用层和基础设施层的概念,以统一的网关层进行概括,并以北向与南向分别体现了来自不同方向的请求。如此形成的对称结构突出了领域模型的核心作用,更加清晰地体现了业务逻辑、技术功能与外部环境之间的边界。

资源库视为防腐层的端口与适配器,作为领域建模时的角色构造型,与场景驱动设计更好地结合,增强了领域模型的稳定性。应用层被去掉之后,被弱化为开放主机服务层的本地服务,相当于从设计层面回归到服务外观的本质,也有助于解决应用服务与领域服务之间的概念之争。

代码模型示例:

9809714772ca38be482a7483c3ee0523.png

ohs 为开放主机服务模式的缩写,acl 是防腐层模式的缩写,pl 代表了发布语言;也可以使用北向(northbound)与南向(sourthbound)取代 ohs 与 acl 作为包名,使用消息(messages)契约取代 pl 的包名。

实际使用中遇到的问题

在实际DDD实践时经常会遇到和spring依赖的冲突。比如在构建DDD充血模型时封装的行为可能会依赖spring注入。如果使用了spring注入,这个充血模型就不是简单的实体对象。这时候一般的解决方法是使用XXHolder来做一层封装。

在使用DDD分层架构来作为工程架构时,如果分层松散,会导致管理混乱;如果严格分层,对于一些额外的层次就不好处理。比如定时任务,严格来做定时任务受外界调度,属于用户接口层,那要专门为定时任务做一个严格的4层模型必要性又不是很大。这时候可以使用依赖倒置进行接口。基础设施层可以贯穿各层注入数据来做松耦合。

26d749f75a6e4dc58ce0ab0361b7456d.png

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值