关于领域驱动

前言

DDD不是一套框架,是一种解决复杂问题的思想。

我们是在面向对象吗?

项目中充斥着大段大段的事务脚本型代码

术语

  • 领域 边界

  • 统一语言

  • 限界上下文的划分

  • 在一个限界上下文的内部包含核心子域,支持子域,通用子域

  • 失血 贫血 充血

  • DP模型 Domain Primitive 充分体业务域,比如对于手机号这个字符串,使用一个PhoneNumber类来代替

    • 隐性的概念显性化
    • 隐形的上下文显性化
    • 封装多对象行为
  • 实体 值对象 领域服务 仓储 工厂

  • 聚合 聚合根

  • 领域事件 发布-订阅模型

  • 架构对比 三层 四层 CLEAN 六边形 CQRS 防腐层(Anti-Corruption Layer, ACL)

  • ddd下的架构模式

  • 事件溯源 事件驱动架构EDA 分布式事务 saga模式

  • kafka

领域模型设计的特点和难点

  • 发现问题,理解问题,解决问题
  • 领域确定:事务的自身特性和所处的上下文环境
  • DDD如何解决复杂性:通过领域,有界上下文来进行拆分;在领域内部,通过一些模式,技巧来实现。
  • 注重产品的程序员
  • 统一术语,这个必须确定,保证大家统一,不会理解错误。
  • 业务策略,业务规则,业务流程,然后和熟悉相关内容的人员多次沟通,确定领域边界。
  • 领域模型提炼:简单准确,通用统一,逻辑严格。
  • 第一性原理:从真实的问题出发,追本溯源,理性推演,不参照不比较,客观地计算和创造出解决问题的方案

怎么划分上下文

啥是聚合

看的时候竟然发现和之前画UML的时候里面聚合组合搭上了,可是UML里面的我已经忘记了。我又回头看了下,觉得应该和UML类图中的组合类似,聚合在一起的具有相同的生命周期

事件溯源

一些说明

应用服务和领域服务:判断什么时候应该定义领域服务,什么时候应该定义应用服务,一个根本的判断依据是看需要封装的职责是否与领域相关

防腐层(ACL):客户端自己的域模型为客户提供功能。该层通过其现有接口与另一个系统进行通信,几乎不需要或不需要对其进行任何修改。因此,防腐层隔离不仅是为了保护您免受混乱的代码的侵害,还在于分离不同的域并确保它们在将来保持分离。

DDD是为了解决复杂的业务问题,并不一定需要特定的架构(类似cqrs这样)

实际使用过程中的一些问题

查询操作,不进行不同层直接的数据对象转换,可以直接从仓储层捞出来,组装即可。

对于适配层,还是觉得需要做一层对象转换,将外部的参数转换成应用层需要的参数,将应用层的结果转换成外部需要的参数;

思考

看了之前做的common-architecture项目,发现好像和自己做的初衷有点不一样,首先我们需要ddd中的领域的模型,讲复杂的业务通过领域划分出来,对应的业务在各自的领域中去处理,尽量在代码中避免事务型脚本;

我们并不一定非得需要CQRS这样的架构模型实现自己的业务,有时候这样就是增加复杂度;

参考

> 可在下面留言(需要有 GitHub 账号)