概述
《领域驱动设计》软件核心复杂性应对之道。读完之后几个感受:
- 架构设计的从混乱到模式和方法论,后面会说
- 复杂问题依然还有“具体问题具体分析”的感觉,很能理解方法论是不是严格的数据公式,还是有需要“看手感”的地方。但是书中大致给到了思考方向
- 借鉴经典现有的领域模式是一个值得推荐的方式
- 文中大量引用《分析模式》一书,有时间可以接着读这本
- 一句话概括领域建模的核心:找到真实世界到计算机世界的映射,从三个维度来映射,事物-->对象,行为-->方法,关系-->协议(部分教材可能还有 职责 --> 职责的映射)
通用原则
- 低耦合和高内聚,是通用设计原则。
- “查询修改”分离,也可以认为是一个默认规则
书中提炼出的一个领域建模方法步骤
1 简化需求描述,【提炼“术语表”】
* 通用语言表,便于沟通,语言词汇对应类名,重构要同步修改
* 领域专家有自己的术语,技术团队使用的语言经过调整,便于从设计角度讨论领域,讲话和写东西使用的语言不一致,削弱了知识的消化。
* 解决2: 创建通用词汇:类和主要操作名称,通用词汇的更改,就是对于类的更改。【沟通的时候,直接用类名作为词汇来沟通】。
举例:RoutingService查找满足RouteSpecification的Itinerary。
做到图,模型,代码(类)的统一。-
2 分层设计,目的:拆分出领域层
* 一种分层示范:
- 用户界面层
- 应用层(跟踪查询,事件日志,预定应用等等,领域对象的调度,任务状态)
- 领域层(业务状态和业务规则,技术细节可以由基础设施层提供,这一层是业务软件的核心。用户,物品,事物行为规范,使用记录,地点,Event等)
- 基础设施层(为应用层传递消息,为领域层提供持久化repository,为用户层提供组件)- 在每一层内分别设计,使其具有内聚性,且只依赖它的下层(>>>单方向的依赖)只与上层进行松散耦合,下层调用上层,可以用回调或者observers模式。
-
3 领域层中的设计:
-
拆分core domain,一般用一段话精简描述(考验产品经理)
``` 比如: 航班预定系统,模型可以表示乘客优先级和预定策略, 乘客模型反映出回头客关系, 所以需要乘客的历史记录,参与过的活动以及人员关系。 模型支持航线,座位搜索, 集成到航空预定系统中 ```
领域内部可以继续分层,上面的层知道下面的层做什么,但是下面的层不知道上面的层
领域中的分层参考:
决策层(制定决策)-->策略层(决策依据)-->承诺层(对于用户特殊承诺)-->作业层(行为)-->能力层(能做什么)
-
-
4 领域对象,模型和关联
- 表示模型的元素:module,service,entity,value object
(网上的教程也有其他叫法:实体,服务,值对象) - 生命周期:Factory开始,repository结束
- 注意:dal(数据库映射层,简单一点模型通常和 领域层是一样的结构。早期的J2EE应用一个领域对象对应一个bean,但是这个方式影响开发效率和程序效率),复杂一点的领域是对象数据 + 行为方法
- entity中注意id的设计
- 系统如果比较大,模型提炼出module,提高内聚
- 不同模型需要明确职责边界,避免多个系统修改同一个模型,增加有歧义属性
- 职责不同的两个context,可以有自己的术语表(方言表,然后建立概念转化映射),就是对象到对象的转化,
- 梳理aggregate边界
- 设计领域中的【关联】,定义查询的方向, 注意为了简化关联查询,可以在entity中加入冗余字段
- 优化关联方式:1 指定关联方向,把多对多简化为一对多(ps:感觉有时候需求要求多对多,难以简化)
- 优化关联方式:2 添加限定符,减少不必要关联
- 表示模型的元素:module,service,entity,value object
-
5 场景走查,
模拟几种功能使用场景,推演系统的可行性
比如:- 一个业务流程:下单
- 复制:prototype模式,复制一个aggregate,比如根据历史订单再创建一条
其他提升设计能力方法
- 1 扩充领域知识,可以借助书本
- 2 咨询领域专家
- 3 现有模型和架构设计学习
- 4 图是一种沟通手段,简洁的小图更好的实现沟通目标。
另一种设计方式:Smart UI
smart ui完全违反领域设计原则,用户界面中实现所有逻辑,分别绑定用户界面和业务逻辑,实现可视化编程,处理的数据通过数据库共享。这个模式自有其好处,但是和领域设计原则不同。
实践
面向对象也有 贫血模型 和 充血模型
充血模型中也可以定义方法。
所以更多的区别在于:子域 + 聚合
领域建模实践中的工具和方法
- 1 事件风暴会议
- 2 子域划分
- 3 找到领域聚合根
- 4 领域模型词汇表
以银行转账的例子:
账号(Account)是以下两部分的聚合根:
- 客户信息(CustomerInfo)Entity
- 值对象(Address)
词汇表:
- 账号
- 客户信息
- 地址
子域(分而治之)
电商包含:选购,下单,支付,物流多个子域
在线订餐:下单,接单,配送等子域
联邦学习:数据接入,数据加工,训练,预测多个子域
复杂系统的领域建模:是子域为中心的领域建模,一个个的领域模型设计,称为界限上下文。
聚合根
聚合,是领域驱动设计中重要的概念
表达,真是世界中整体和部分的关系。
比如:订单的保存,是一个领域的行为,内部可能有多个关联对象的保存,事务属性等,事件消息。