洞见领域驱动设计
2021-06-24 08:48:13 0 举报
AI智能生成
洞见领域驱动设计
作者其他创作
大纲/内容
1、综述
架构设计的响应力
什么是架构设计?
首先要解决问题复杂度
设计脱离架构,其次要建立团队协作沟通的共识
让系统能够更快地响应外界的变化,能持续演进
面向业务变化而架构
组件的划分尽量靠近变化的原点,将变化“隔离”在一定范围(组件)内
组件之间能够互相调用,但彼此之间不应该有强依赖
鼓励组件在业务上的复用
打造架构响应力的方法
解决
让团队中各个角色都能够采用统一的架构语言
避免组件划分过程中的边界错位
让业务架构和系统架构形成绑定关系
建立针对业务变化的高响应力架构
领域模型的应用
业务对象的抽象
讲故事
这个子域解决的业务问题or提供的业务能力
抽象出
实体(Entity)
唯一标识
生命周期
值对象(Value Object)
简单
聚合的封装
聚合(Aggregate)
建筑学:骨料
形成混凝土的重要元素,也是为什么混凝土如此坚固的基础
用途
对骨干业务规则的封装,提高内聚性
领域服务的定义
类比:静态方法
拥有一定的逻辑但不持有任何的信息
eg. 转账
Service 的限定
领域服务(Domain Service)
应用服务(Application Service)
对外API
Repositories 的使用
相关概念
DAO(Data Access Object)
数据与对象之间的映射关系
Repositories
更加粗粒度的抽象,映射对象是聚合
限界上下文(Bounded Context)的意义
一个限界上下文封装了一个相对独立子领域的领域模型和服务
界限上下文地图描述了各个子领域之间的集成调用关系
业务问题 => 多个子域问题(subdomain) => 多个限界上下文
分层架构的代码结构
分层架构
代码目录
模型表达
依赖关系
测试实现
子主题
By Experience
没有一套方法和一套架构能够打遍天下
问题、问题、问题
区分
问题域
解决方案域
跨领域合作
团队共同学习 > 建模本身的正确性
从需求到代码
刻意“失败”
通过实践积累经验
2、通用语言、领域、限界上下文
如何说好一门通用语言
当Subdomain 遇见Bounded Context
3、架构
从三明治到六边形
端口和适配器架构
4、领域事件
识别领域事件
大概说
领域事件
领域事件是用特定方式(已发生的时态)表达发生在问题域中的重要事情
领域通用语言(UL)的一部分
eg.宠物猫
宠物主人
疫苗已注射、猫粮已饲喂
宠物医生
病情已确诊、药方已开治
事件风暴
在DDD 建模过程中,以领域事件为线索逐步得到领域模型
1、组织没有领域专家
业务人员
清楚有什么功能(What)
领域专家
清楚为什么有这些功能(Why)
补救措施
Before: 组织业务愿景和场景分析
与业务干系人对齐业务愿景,一起分析业务场景背后的问题域
After: 再展开事件风暴
2、面向复杂业务系统的事件风暴
分而治之
将业务干系人分成多组,组织多轮事件风暴
一个业务主线
按照业务结点进行分组
公共结点
按每条业务线分组展开事件风暴
再针对多组产出结果进行统一业务抽象
3、领域专家的专业表述
留心表达
当....
如果发生...
当...的时候请通知我
发生...时
4、事件风暴all 领域事件?
我们不关注所有事件,仅关注对干系人解决特定问题有价值的事件
在微服务中使用领域事件
当提到“事件驱动”时,我们在说什么?
5、微服务
DDD & Microservices
服务拆分与架构演进
溯源微服务
6、示例实现
后端开发实践系列
开发者的第0个迭代
第一步:写好README
一键式本地构建
目录结构
基于业务分包
基于技术分包,修改业务代码,多个包导航
提交代码也是散落的,无法直观看出修改的什么业务功能
可以整体迁移业务包
自动化测试分类
单元测试
组件测试
API 测试
日志处理
在日志中加入请求标识,方便链路追踪
集中式日志管理
异常处理
统一代码风格
静态代码检查
健康检查
API 文档
数据库迁移
多环境构建
CORS
常用第三方库
领域驱动设计(DDD)编码实践
DDD 总览
战略设计
子域和限界上下文(Bounded Context,BC)的划分,各个BC 之间的关系
战术设计
聚合根、应用服务、资源库、工厂等
实现业务的3种常见方式
1. 基于“Service + 贫血模型”的实现
2.基于事务脚本的实现
3.基于领域对象的实现
基于业务的分包
领域模型的门面——应用服务
业务方法与业务用例一一对应
业务方法与事务一一对应
本身不应该包含业务逻辑
与UI或通信协议无关
接受原始数据类型
业务的载体——聚合根
聚合根的实现应该与框架无关
聚合根之间的引用通过ID完成
聚合根内部的所有变更都必须通过聚合根完成
通过消息机制异步更新其他聚合根
聚合根不应该引用基础设施
外界不应该持有聚合根内部的数据结构
尽量使用小聚合
实体 vs 值对象
实体(Entity)
生命周期 + 全局唯一标识(ID)
值对象(Value Object)
起描述性作用的对象
不变的(Immutable)
聚合根的家——资源库
Repository VS DAO
DAO的设计初衷只是对数据库的一层很薄的封装
Repository是更偏向于领域模型
仅仅聚合根
纯粹的Repository
save() & findById()
读操作和写操作分离
创生之柱——工厂
将“聚合根的创建逻辑”显现出来
实现方式
直接在聚合根中实现Factory方法
简单的
独立的Factory类
复杂的 or 不适合放在聚合根上
必要的妥协——领域服务
越少越好
Command对象
好处:查找所有后缀为Command的对象,便可以概览性地了解软件系统向外提供的业务功能
DDD中的读操作
原则
领域模型中的对象不能直接返回给客户端
3 种方式
基于领域模型的读操作
优点
简单明了
缺点
读操作完全束缚于聚合根的边界划分
基于不同的查询条件返回数据(混入过多查询逻辑)
基于数据模型的读操作
优点
读操作的过程不用囿于领域模型
缺点
数据库主要是对应于聚合根的结构创建的,因此读操作依然会受到写操作的数据模型的牵制
CQRS
事件驱动架构(EDA)编码实践
领域事件的建模
创建领域事件
发布领域事件
事件表:本地事务保存事件对象,然后再发送消息
在应用服务(ApplicationService)中发布
在资源库(Repository)中发布
消费领域事件
消费方的幂等性
消费方有可能进一步产生事件
事件驱动架构的2种风格
事件通知
事件携带状态转移(Event-Carried State Transfer)
基于RabbitMQ的示例项目
......
简单可用的CQRS 编码实践
用DDD实现打卡系统
7、扩展阅读
DDD 该如何学?
领域驱动设计(DDD)实现之路
从“四色建模法”到“限界纸笔建模法”
可视化架构设计——C4 介绍
从架构可视化入门到抽象坏味道
技术债治理的四条原则
0 条评论
下一页