天天看点

DDD领域驱动设计(Domain Driven Design)DDD

DDD

领域模型设计的常见误区

可以将DDD看成一种开发思想体系,它促成了一种新的以领域为中心的思维方式。它是一种学习过程,而非终极目标。DDD并非一种严格的方法论,而是必须和一些迭代式方法论结合使用才能构建并演化出一个有用的模型。

DDD并不是一种面向对象的设计,也不是一种面向代码为中心的思想体系或者模式语言。DDD与其说是设计模式,不如说是通过协作来解决问题的方法。

领域模型专注于领域逻辑,要与技术复杂性分开

有效提炼知识的模式

草图

CRC图

影响地图

领域划分

核心领域:是需要花大精力来投入的,需要当做一个产品来不断迭代创新保证其核心竞争力

通过领域:比如:邮件发送服务、短信发送服务,没有他们系统也无法运转,不用花费大精力和财力投入,相反应该寻求购买用于通用域的软件

支撑领域:用于支撑核心领域服务,也应该寻求现成的解决方案

专注于清晰边界而非完美模型:并非每个领域我们都要花大精力投入,非核心领域采用大泥球模式也未尝不可,只要他能够运行就好,只要他们被划分在清晰的边界内

领域模型

业务模型:

分析模型:先找事件,再找出与事件关联的实体,值对象附属于实体,不单独存在

代码模型:只需建模出满足用例的模型就够了,领域建模不用模拟现实世界的所有行为,这样只会增加工作量

分层设计

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yRiuUyyK-1621518257858)(img/分层设计.png)]

领域对象

实体Entity

拥有唯一标识符的对象,一般需要用来持久化;实体内值相等不代表就是同一个实体,必须依靠唯一标识符判断;实体一般有生命周期;具有身份;

为了让实体类不过于臃肿,可以考虑把行为动作放在值对象和领域服务中

经验:使用规范实现校验;使用状态模式或者显示建模(推荐)处理状态变更影响不同的行为;使用备忘录(快照)模式处理返回只读对象的情况

值对象valueObj:

没有身份,不关心他的唯一标识符(也就是不存在),只关心他属性的对象。极力推荐值对象是不可变的,由构造器创建

服务:

一些领域中的动作,它们是一些动词,看上去却不属于任何对象,通常跨多个对象;服务也分层,比如:应用服务、领域服务

模块Module:

模型越来越大,将达到一个作为整体很难讨论的点。将模型组织进模块,被用于组织相关概念和任务以降低复杂性,增加内聚性,降低耦合度;模块应该由在功能上或者逻辑上属于一体的元素构成

聚合Root:

用来定义对象所有权和边界的领域模式。每个聚合有个根,它是外部可以访问的唯一对象,这意味着其他对象不能对根内的对象进行操作,只能让根来执行某些活动;如果根被删除,根内的所有对象都要被删除;如果聚合根被建立,他的所有内部对象都将被建立,如果一个对象不能被正常创建,将产生一个异常;如果要把根内部对象传递给外部,可以做一份拷贝,这些保证对拷贝的修改不会影响聚合的一致性;如果聚合对象被保存到数据库,只有根可以通过查询来获得,其他对象只能通过根导航关联来获得。聚合内的对象可以允许持有其他聚合类对象的根引用。

原则:1、选择单一编译方向;2、选择id而不是对象引用;3、使用一致性边界;4、使用较小的聚合

工厂Factory:

帮助处理对象的创建。实体和聚合可能会很庞大和复杂,通常某些事物通常是有其他事物创建的,所以需要工厂的来创建。通过构造函数来创建和领域本身是冲突的,相当于让客户端来维护领域内的关系和规则,这相当于让领域内的一部分责任转移到了外部(就像给我们轮子、引擎,让我们自己取构造汽车)。

资源库Repository:

处理对象的存储问题,封装所有获取对象引用所需要的逻辑。是领域模型的范畴,会调用基础设施。

领域事件

领域事件也分为内部事件和外部事件,内部事件由领域模型内部响应处理,外部事件更多的是由应用服务响应处理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fd7d6gIJ-1621518257861)(img/领域对象关系.png)]

服务的3个特征:

  1. 服务执行的操作涉及一个领域概念,这个领域概念通常不属于一个实体或者值对象。
  2. 被执行的操作涉及到领域中的其他的对象。
  3. 操作是无状态

其他意识

应用层是很薄的一层,他可以调用领域层,也可以直接调用基础设施层

调用领域层必须经过应用层

领域对象之间的关联应该尽量消除

脱离了模型设计会导致软件不能反映它所服务的领域

建模的第一件事是阅读业务规范,从中寻找名词和动词。名词被转化为类,动词被转化为方法。

把约束、过程、规约放在一个方法中,如果比较复杂就放在应用层

防奔溃层:Facade,每个Facade增加一个适配器Adapter

Application层 可以直接调用repository,咱们是读写分离CQRS模式。写的必须一层一层的调用,读可以不经过domian

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yzvpqeOL-1621518257865)(img/领域边界.png)]

CQRS(命令查询责任分离)

这种模式会将领域模型分为两个模型:读取模型和写入模型

继续阅读