总结上一篇DDD: 将数据为核心 处理业务 转变为 以业务为核心 产生 数据 从而达到下面4个效果
通用语言 统一思想:统一项目各方业务、产品、开发对问题的认知,而不是开发和产品统一,业务又和产品统一从而产生分歧。
领域抽象 明确分工:域模型需要明确定义来解决方方面面的问题,而针对这些问题则形成了团队分钟的理解。而且抽象开来
领域模型 反映变化:需求是不断变化的,因此我们的模型也是在不断的变化的。领域模型则可以真实的反映这些变化。
可伸缩性 边界分离:领域模型与数据模型分离,用领域模型来界定哪些需求在什么地方实现,保持结构清晰。
以业务为核心的 DDD 改如何设计呢?
战略设计: 就是确定项目定位:核心域 支撑域 通用域 相关人员 把业务 拆分 将各个 领域(业务模块) 领域模型(需要哪些内容/什么操作)
战术设计:按照战略设计 则从技术视角出发 实现代码构造 那么如何构造体系就需要了解一些DDD概念。
(从网上找了个图片)
实体 注意 代表的是个体业务实体 就是有哪些内容信息 哪些操作 (代码性 好比是 类class 里面哪些属性 方法行为操作啊) 与 数据库映射的实体 不同 因为有业务行为操作在里面定义
比如说 实体1 代表开发部门人员1号 实体2 代表开发部门人员2号
有唯一标志的核心领域对象,且这个标志在整个软件生命周期中都不会发生变化。
这个概念和我们平时软件模型中和数据库打交道的Model实例比较接近,唯一不同的是DDD中这些实体会包含与该实体相关的业务逻辑,它是操作行为的载体。
值对象 就是业务实体里面的描述属性 (代码性就是 属性值 只不过有单一属性值对象 或者 多属性值对象(相同描述的属性合集))
之前设计都是按照数据库范式 单一属性值,那么出现一对多的关系 比如 一个人 俩个地址 人是实体 地址也是实体 那就需要2行数据呈现 就得建一张地址表
其实没必要 在管理人的业务层面来看 无非就是个地址描述 搞那么复杂关联干啥,所以呢 将这些 可能存在 一对多关系 的 描述属性值 集合 变成一个 多属性值对象 或 大json对象
以多属性值对象替换实体数据表 从而在业务上看 属性聚合了 而且在 数据库设计上 也简化了 省去地址表了 就是有一点不好 维护多属性值对象 不像 单属性值对象好维护 而且需要根据业务看 不是越多越好
比如 公司给员工的居住地址 省市区 那这三个属性值可以打包成 地址 存到一个对象属性值中 毕竟开发人员 对于这些描述 属性 不是重点
但是 如果业务层面是 地址管理 那这个地址 就为实体了 省市区 可能就是三个 单一属性 关联的 居住人员 可能就是 多属性值对象了
虽然优势是可简化DB复杂度。但若使用不当,优势就会成劣势。所以必须理解值对象的适用场景。
值对象采用序列化大对象的方式简化DB设计,减少实体表的数量,可简单、清晰表达业务概念。该方式虽然降低DB设计复杂度,却无法满足基于值对象的快速查询,导致搜索值对象的属性值变难。
值对象采用属性嵌入的方式提升了DB性能,但若实体引用的值对象过多,则会导致实体堆积一堆缺乏概念完整性的属性,这样值对象就会失去业务含义,操作也不方便。
所以对照优劣势并结合实际业务场景,才能发挥值对象的最大作用。
聚合根 根实体(业务主实体) 聚合小领域入口 跟另一个聚合沟通的桥梁 (代码性 个人理解很像 这个聚合中 的老大实体 别的实体都是小弟 附属于它 类似之前设计中主从表 最外层主表)
比如开发部门 的 领导 虽然领导也是一个实体 但是他的实体比员工实体多了一个操作行为 是管理
他跟别的部门需要沟通 如果有个需求需要 人事部和开发部一起商量 那必然是 领导出面 然后下发任务
聚合 (小/子领域) (没有代码性 单纯概念性 将业务整合 高聚合 低耦合 ) 就是将 一个个的实体和依附于实体的值对象 进行一个 内聚然后 在业务上 让聚合根进行一个管理
比如 开发部门 里面好多开发人员 聚在一块 有问题协商交流方便
实体和值对象表现的是个体的能力,而我们的业务逻辑往往很复杂,依赖个体是无法完成的,这时候就需要多个实体和值对象一起协同工作,而这个协同的组织就是聚合。
聚合是数据修改和持久化的基本单元,同一个聚合内要保证事务的一致性,所以在设计的时候要保证聚合的设计拆分到最小化以保证效率和性能。
聚合的体现就是仓储
仓储 (代码概念) 实现持久化 这个下一章 将在代码结构说明
限界上下文 其实就是 聚合的边界 比如 人事部 开发部 有界限
业务单一职责 高内聚 创造出来的聚合 边界就是 业务分界
领域事件
在特定的领域由用户动作触发,表示发生在过去的事件。
比如领导下发任务/员工提交任务事件。
领域服务/领域行为 (代码性 就是 将一些方法放到一起管理)
对单个领域之间 各个聚合之间行为规范管理
应用服务/应用行为
对多个领域之间 行为的规范管理
疑问解答:
1 聚合根 / 实体 /值对象 区别
聚合根 全局唯一标识
实体 聚合内唯一标识 哪怕属性都变了 也是同一个实体
值对象 没有标识 值变了 那就是新的值了
2 生命周期
聚合内 随聚合根一同消失
3.比较实体相等
判断聚合内 实体id 值对象 就所有属性对比相等
4看业务
实体和值对象也可能随着系统业务关注点的不同而更换位置。比如,如果另一个限界上下文更关注地址,而不关注与这个地址产生联系的人员,那就把地址设计成实体,人员设计成值对象