《解构领域驱动设计》阅读
软件复杂度挑战:
- 规模——以子领域、限界上下文对问题空间与解空间分而治之
- 结构——以分层架构隔离业务复杂度与技术复杂度,形成清晰的架构
- 变化——通过领域建模抽象为以聚合为核心的领域模型,响应需求的变化
领域驱动设计统一过程(Domain-Driven Desigh Unified Process, DDDUP)分为三个阶段:
- 全局分析阶段
- 架构映射阶段
- 领域建模阶段
开篇
1. 软件复杂性
复杂系统:由大量相互作用的部分组成的系统。与整个系统比起来,这些组成部分相对简单,没有中央控制,组成部分之间也没有全局性的通信,并且组成部分的相互作用导致了复杂行为。
软件系统的复杂性同时体现在理解能力上的复杂难解(complicated),和预测能力上的复杂难测(complex)。
- 理解能力的影响因素:
- 规模:主要由软件需求决定,需求的数量及其内在关系
- 结构:由系统的质量属性决定,UPRS等非功能性需求
- 细节层面,代码污浊不堪,违背了“高内聚低耦合”的设计原则
- 架构层面,缺乏清洗的边界,各种通信与调用依赖纠缠在一起
- 预测能力的影响因素:
- 变化:在架构设计时期,如何准确预测变化发生的可能性,从而作出相应的设计以作应对
- 过度设计:过度抽象,增加了方案的复杂度,但预期的变化并没有发生
- 设计不足:没有识别出可能会发生的变化,导致方案缺乏可扩展性,后期修改成本过高
- 变化:在架构设计时期,如何准确预测变化发生的可能性,从而作出相应的设计以作应对
2. 领域驱动设计概览
2.1 基本概念
领域驱动设计元模型的要素关系如图所示
领域驱动设计的核心是模型驱动设计,而模型驱动设计的核心是领域模型,领域模型必须在统一语言的指导下获得。
领域模型分类:
- 核心子领域
- 通用子领域
- 支撑子领域
引入限界上下文来确定业务能力的自治边界,通过持续集成来维护模型的统一
领域模型的设计要素:实体、值对象、领域服务、领域事件
聚合是一种边界,可以封装一到多个实体与值对象,并维持该边界范围内的业务完整性。聚合至少包含一个实体,且只有实体才能作为聚合根。
工厂(factory)和资源库(repository)负责管理聚合的生命周期。
2.2 问题空间与解空间
软件系统的构建实则是对问题空间的求解,以获得构成解空间的设计方案
对客户提出的问题,需要分清楚什么是问题,什么事解决方案,即“问题级需求”与“方案级需求”的区别
“问题级需求”才是在问题空间理解客户需求,
对于问题空间,强调运用统一语言来描述需求问题,利用核心子领域、通用子领域与支撑子领域来分解问题空间
2.3 战略设计与战术设计
- 战略设计:
- 问题空间:对问题空间进行合理分解,识别出核心子领域、通用子领域和支撑子领域,并确定各个子领域的目标、边界和建模策略。
- 解空间:对问题空间进行解决方案的架构映射,通过划分限界上下文,为统一语言提供知识语境,并在其边界内维护领域模型的统一。
每个限界上下文的内部有着自己的架构,限界上下文之间的协作关系则通过上下文映射来体现和表达。
- 战术设计:如果选择了领域模型模式,此时要在限界上下文开展领域建模。在限界上下文内部,需要通过分层架构降临太过于独立出来,在排除技术实现的干扰下,通过与领域专家的协作在同一语言的指导下逐步获得领域模型。
从战略设计到战术设计是自顶向下,为设计原则对设计决策的指导;
将战术设计方案反馈给战略设计,是自底向上的演化过程,为对领域概念的重构引起对战略架构的重构。
2.4 领域模型驱动设计
模型驱动设计是面向领域的,遵循两大原则:
- 以领域为建模驱动力:在建模过程中,针对领域知识提炼抽象的领域模型,并不断针对领域模型进行深化与突破,知道最终以代码来表达领域模型。
- 排除技术因素的干扰:领域建模与技术实现的关注点分离有助于保证领域模型的纯粹性,也能避免混淆领域概念和其他只与技术相关的概念。
2.5 领域驱动设计过程
- 面对客户需求,由领域专家与开发团队展开充分交流,经过需求分析与知识提炼,获得需求明确的问题空间。
- 从问题空间的业务需求提炼统一语言,利用子领域分解问题空间,根据价值高低确定核心子领域、通用子领域和支撑子领域。
- 通过对问题空间开展战略层次求解,获取限界上下文形成解空间的主要支撑元素。
- 遵循“高内聚松耦合”的原则划分领域知识的边界,在通过上下文映射管理它们之间的关系
- 通过分层架构将衔接上下文内部的领域隔离出来,进行面向领域的模型驱动设计(战术设计阶段)
- 选定一个限界上下文,进行领域分析,提炼领域知识建立满足统一语言要求的领域分析模型,然后引入实体、值对象、领域服务、领域事件、聚合、资源库和工厂等设计要素开始程序设计,获得设计模型之后在其指导下进行编码实现,输出最终的领域模型、
领域驱动设计过程
2.6 如何控制了软件复杂度
- 控制规模:战略设计阶段,采用限界上下文和上下文映射分解问题空间,降低单个子领域的规模
- 清晰结构:通过分层架构将领域分离出来,在业务逻辑(业务需求)与技术实现(质量需求)之间划定一条清晰的边界。
- 业务需求之间的复杂关系也会导致系统结构混乱不堪
- 响应变化:领域驱动设计通过模型驱动设计针对限界上下文进行领域建模,形成了结合分析、设计和实现于一体的领域模型。
3. 领域驱动设计统一过程
领域驱动设计的不足
- 领域驱动设计缺乏规范的统一过程:没有统一过程去规划战略设计和战术设计阶段需要执行的活动、交付的工作以及阶段里程碑。
- 领域驱动设计缺乏与之匹配的需求分析方法:
- 领域驱动设计缺乏规范化的、具有指导意义的架构体系:
- 领域驱动设计的领域建模方法缺乏固化的指导方法:
3.1 统一过程的二维模型
参考了统一过程(rational unified process. RUP)
3.2 统一过程的动态结构
结合领域驱动设计对问题空间和解空间的阶段划分、对战略设计和战术设计的层次划分
过程工作流
- 全局分析阶段:探索与分析问题空间,获得以业务服务为业务需求单元的全局分析规格说明书
- 价值需求分析:识别目标系统的利益相关者,明确系统愿景,识别系统范围。
- 业务需求分析:
- 根据用户发起的服务请求,梳理出提供业务价值的动态业务流程,体现
了多个角色在不同阶段进行协作的执行序列。 - 根据业务流程的时间节点,在业务目标的指导下将业务流程划分为不同时间阶段的多个业务场景。
- 业务场景由多个角色参与,划分每个角色在该场景下与目标系统的一次功能交互,由此得到业务服务
- 根据价值需求分析结果,将不同的业务需求划分到不同的领域(核心、通用、支撑)
- 根据用户发起的服务请求,梳理出提供业务价值的动态业务流程,体现
- 架构映射阶段:从组织级、业务级和系统级3个层次完成对问题空间的求解,映射为遵循领域驱动架构风格的架构映射战略方案。
- 组织级映射:根据价值需求,确定解空间的边界,通过系统上下文呈现利益相关者、目标系统与伴生系统的关系
- 业务级映射:根据业务需求,对业务服务表达的业务知识进行归类与归纳,识别出边界相对合理的限界上下文。
- 限界上下文内存遵循菱形对称架构模式;
- 限界上下文之间通过不同的上下文映射模式表达协作方式,规范服务契约
- 系统级映射:在划分好的子领域的指导下,在系统上下文的边界内部建立系统分层架构
- 业务价值层:核心子领域的限界上下文的映射结果
- 基础层:通用子领域和支撑子领域的限界上下文
- 边缘层:为前端提供统一的网关入口
- 领域建模阶段:对问题空间战术层次的求解过程,目标是建立领域模型
- 领域分析建模:以领域专家为主导,针对限界上下文对应的领域开展分析建模,形成领域分析模型
- 里程碑目标:业务服务规约和领域模型概念图
- 领域设计建模:以开发团队为主导,围绕每个完整的业务服务开展设计工作,获得领域设计模型
- 里程碑目标:以聚合为核心的静态设计类图和由角色构造型组成的动态序列图与序列图脚本
- 领域实现建模:以开发团队为主导,在拆分业务服务为任务的基础上开展测试驱动开发,编写出领域相关的产品代码和单元测试代码,形成领域实现模型
- 里程碑目标:实现业务功能的产品代码和验证业务功能的测试代码
- 领域分析建模:以领域专家为主导,针对限界上下文对应的领域开展分析建模,形成领域分析模型
统一过程的静态结构
过程工作流与设计元模型
| 过程工作流 | 模式 | 方法 |
|---|---|---|
| 价值需求分析 | 统一语言 | 商业模式画布 |
| 业务需求分析 | 统一语言、核心子领域、通用子领域、支撑子领域 | 业务流程图、服务蓝图、业务服务图、事件风暴 |
| 组织级映射 | 系统上下文 | 系统上下文图、业务序列图 |
| 业务级映射 | 限界上下文、上下文映射、菱形对称架构 | V型映射过程、事件风暴、服务序列图、康威定律、领域特性团队 |
| 系统级映射 | 核心子领域、通用子领域、支撑子领域、系统分层架构 | 康威定律 |
| 领域分析建模 | 统一语言、限界上下文、模型驱动设计 | 快速建模法、事件风暴 |
| 领域设计建模 | 统一语言、模型驱动设计、实体、值对象、聚合、领域服务、领域事件、资源库、工厂、事件溯源 | 角色构造型、服务驱动设计 |
| 领域实现建模 | 统一语言、模型驱动设计 | 测试驱动开发、简单设计、测试金字塔 |
全局分析阶段
4. 问题空间探索
5W模型包含价值需求和业务需求,他们共同组成了目标系统的问题空间
- 价值需求
- Who: 利益相关者
- Why: 系统愿景
- Where: 系统范围
- 业务需求
- When: 业务流程
- What: 业务服务
问题空间
- 核心子领域:满足了最重要的利益相关者的价值需求
- 通用子领域:属于业务需求的一部分,但没有鲜明的领域特征,在面向各个领域的业务系统中都能看到,是不具个性的通用功能
- 支撑子领域:某业务服务为另外提供了核心价值的业务服务提供支撑,具有辅助价值但不具有通用意义
达成共识
- 从利益相关者了解到的需求并非最终用户的需求
- 无效的沟通方式,会使得需求的理解偏差导致结果与预期大相径庭
- 理解的需求没有揭示完整的领域知识,导致领域建模与设计出现偏差
如何避免出现偏差:通过绘图、使用便签、编写用户故事或测试用例等可视化的方式展现各自的认知结果
获得统一语言就是在全局分析过程中不断达成共识的过程,即团队各个角色就系统愿景、范围和业务需求达成一致
- 统一的领域术语,尤其是基于模型的语言概念,是让沟通达成一致的前提
- 描述领域行为,是对业务过程的描述,其体现了更加完整的业务需求以及复杂的业务规则
- 从领域的角度而非实现角度描述领域行为
- 若涉及领域术语,必须遵循术语表的规范
- 强调动词的精确性,符合业务动作在改领域的合理性
- 要突出于领域行为有关的领域概念
- 清晰的表达出统一语言蕴含的领域概念,避免认知偏差
- 建立统一语言不限于全局分析阶段,实际上贯穿了整个领域驱动设计统一过程
高效协作方式
- 商业模式画布
商业模式画布 - 业务流程图
- 泳道图:横轴部门/岗位维度;纵轴阶段维度
泳道图
- 泳道图:横轴部门/岗位维度;纵轴阶段维度
- 服务蓝图:服务设计的主要工具,更加全面的展示了客户与前台员工、前台员工与后台员工、后台员工与内部支持者之间的协作。因此服务蓝图能够全方位地展现具有完整业务价值的业务流程
- 一个服务蓝图对应一个业务流程
服务蓝图
- 一个服务蓝图对应一个业务流程
- 用例图:
- 业务用例:组织外的角色与组织之间的一次交互,代表了组织的本质价值
- 系统用例:角色与目标系统之间的交互
用例图
- 事件风暴
- 以事件为核心驱动力开展业务探索
- 强调可视化的互动,更好地调动所有参与者共同对业务展开探索
- 两个层次:
- 探索业务全景:属于宏观层次,寻找业务流程产生的时间,形成一个全景的事件流
- 领域分析建模:属于设计层次,通过探索业务全景获得的事件流,围绕着事件获得领域分析模型
- 学习循环:视觉会议协作方式将个人的学习过程转变成群体共同工作的学习过程
- 对意图和任务焦点的想象
- 探索与投入
- 思考和发现模式
- 决定行动与应用
5. 价值需求分析
价值需求分析会对整个目标系统进行价值判断,识别利益相关者、明确系统愿景、确定系统范围,从而构成全局分析阶段要获得的价值需求。
可以使用商业模式画布来进行可视化的价值需求分析
5.1 识别利益相关者
利益相关者:积极参与项目、受项目结果影响,或者能够影响项目结果的个人、团队或组织
- 狭义:与目标系统存在利益关系的个人、团队或组织
- 广义:与目标系统相关的整个企业乃至整个行业生态圈的大背景
根据征信利益和反向利益确定相关者
- 正向利益:展望目标系统的成功开发会给哪些人或者角色带来价值
- 价值:目标系统带来的经济价值、提高工作效率、改进工作流程等等
- 反向利益:目标系统的开发遭遇障碍时会影响哪些人
利益相关者分类
- 受益的~:从目标系统的业务需求获取价值的人,即“受益者”
- 解决问题的~:为目标系统的成功开发提供价值的人,即“支持者”
在价值需求分析阶段,支持者更加重要,他们决定目标系统的愿景与范围,确定开发目标系统的约束条件;在业务需求分析阶段,受益者更加重要,他们决定了目标系统的业务流程与业务场景,前提是这些业务需求必须获得支持者的认可。
5.2 明确系统愿景
系统愿景是对目标系统价值需求的精炼提取,帮助团队就项目目标达成共识
即用言简意赅的话概括项目目标即可
- 电梯演讲法
- 产品名称
- 产品所属类别
- 描述目标客户的需求或机会
- 阐释产品能够带来的关键价值(或购买的理由)
- 与竞争产品的不同
5.3 确定系统范围
确定系统范围就是确定目标系统问题空间的边界
系统范围保证了问题空间的开放性,同时又能确保问题空间内业务需求的收敛性
- 将不合理的、无效的需求拒之门外,确保了业务需求的收敛性
- 允许符合认定的方向的新的业务需求被接纳,保证了问题空间的开放性
业务目标是系统边界的判定标准。通过需求调研获得的原始需求,必须吻合系统范围中目标列表的其中一条或多条目标,才被认为是问题空间中业务需求的一部分。
6. 业务需求分析
属于问题空间的业务需求一定要从用户视角展开,属于“问题级需求”
- 业务流程:体现了一个完整的业务价值
- 业务场景:在一个阶段内共同满足多个角色的业务目标,也可认为是该阶段的里程碑目标
- 业务服务:系统为一个角色提供的服务价值
6.1 业务流程
定义:系统内部以及系统之间通过一系列的协作各自履行不同的业务职责,共同满足该服务请求对应的各阶段业务目标,从而为用户提供业务价值,该过程称为业务流程
两个关键点
- 完整:一个有效的服务流程必须是完整的、端到端的服务过程
- 发起一个业务流程必有起因,也必有结果
- 原因只有一个,但结果可能很多种
- 边界:
结合系统范围确定边界
分类
- 从特征看:
- 主业务流:从因到果的端到端主体流程
- 变体业务流:主业务流的变体
- 支撑业务流:为主业务流与变体业务流提供支持的辅助流程
- 从发起者看:
- 外部业务流:由组织外用户主动发起服务请求
- 内部业务流:由组织内用户主动发起服务请求
- 管理业务流:由负责管理职能的业务部门人员主动发起,且该服务请求主要在于实现控制、监督、审批等管理意图的流程
呈现形式:泳道图、服务蓝图
6.2 业务场景
定义:角色之间为了实现共同的业务目标进行互动的时空背景,通过角色在特定时间、空间内执行的活动来推断情景的发展,形成角色与目标系统之间的体验与互动
5W模型:角色(who)、时间(when)、空间(where)、活动(what)、业务目标(why)
一个业务流程的不同阶段体现了不同的业务目标,即一个动态的业务流程是由一个到多个静态的业务场景构成的
业务场景是在业务目标的指导下在时间维度对业务流程的纵向切分
所有角色都是为了满足一个共同的业务目标,这是确定业务场景的关键
6.3 业务服务
定义:角色主动向目标系统发起服务请求完成的一次完整的功能交互,体现了服务价值的业务行为
业务服务的客观判断标准
- 服务价值:决定业务服务是否满足角色的服务请求
- 角色:必须有一个角色作为发起者
- 包括:用户、策略或伴生系统
- 执行序列:业务服务的执行序列意味着执行的所有步骤连续且不可中断,如此才能完成一次功能交互
呈现:用例图
6.4 子领域
- 核心问题
- 核心子领域:目标系统最核心的业务资产,体现了目标系统的核心价值
- 次要问题
- 通用子领域:内容缺乏领域个性,如授权认证、企业组织等业务
- 支撑子领域:为核心子领域提供支撑,例如物流服务需要地图服务
子领域划分的分类策略
- 业务职能:当目标系统运用于企业的生产和管理时,与目标系统业务有关的职能部门往往会影响目标系统的子领域划分,并形成一种简单的映射关系
- 业务产品:当目标系统为客户提供诸多具有业务价值的产品时,可以按照产品的内容与方向进行子领域划分
- 业务环节:对贯穿目标系统的核心业务流进行阶段划分,然后按照划分出来的每个环节确定子领域
- 业务概念:捕捉目标系统中一目了然的业务概念,将其作为子领域
呈现:子领域映射图
架构映射阶段
映射:获得架构的重要手段
- 系统架构
- 系统上下文:由利益相关者、系统愿景和系统范围映射
- 界定了目标系统与伴生系统之间的关系,通过系统分层架构模式进行约束
- 解空间的控制边界
- 限界上下文:业务服务通过对业务相关性的归类与归纳
- 领域模型的知识边界
- 体现了领域模型和业务能力的边界,通过菱形对称架构模式进行约束
- 系统上下文:由利益相关者、系统愿景和系统范围映射
限界上下文是架构映射阶段的基本架构单元
- 定义:封装了领域知识的领域对象在知识语境的界定下,扮演不同的角色,执行不同的活动,对外公开相对完整的业务能力
- 本质特征:是领域模型的知识语境,又是业务能力的纵向切分
- 使得业务架构的业务边界与应用架构的应用边界保持一定的重叠
自治单元的4要素:最小完备、自我履行、稳定空间、独立进化
自治的限界上下文一定遵循菱形对称架构模式
7. 同构系统
同构系统的组成部分可以形成一一对应的映射关系
架构映射阶段的3组同构系统:
- 架构定义的概念系统与架构设计的模式系统:对应架构映射阶段的概念层次
- 问题空间的真实系统与解空间的软件系统:对应架构映射阶段的设计层次
- 设计方案的架构系统页团队组织的管理系统:对应架构映射阶段的管理层次
7.1 概念层次的同构系统
架构是解空间控制软件复杂度的核心力量
- 软件元素的分解能有效控制规模
- 梳理软件元素及外部环境的关系可以清晰结构
- 架构设计与演化原则保证了架构能够响应变化
菱形对称架构,清晰地划分了业务逻辑与技术实现的边界,确定了业务与技术在架构层次的正交关系,使得引起业务架构与技术架构变化的原因被分离开,形成了两种架构之间的松耦合。
- 系统分层架构
- 业务价值层(value-added layer)
- 基础层(foundation layer)
- 边缘层(edge layer)
- 客户端层(client layer)
7.2 设计层次的同构系统
- 组织级映射:站在整个组织的角度,通过全局分析阶段输出的价值需求确定组织级的系统上下文
- 业务级映射:通过全局分析阶段输出的业务需求,根据业务相关性对业务服务进行归类与归纳,识别出边界合理的限界上下文,并为其建立菱形对称架构
- 系统级映射:进入系统内部,在全局分析阶段划分的子领域知道下,建立系统分层架构,将属于核心子领域的限界上下文映射为业务价值层,将通用子领域和支撑子领域的限界上下文映射为基础层,并确定他们之间协作的上下文映射模式,定义服务契约
8. 系统上下文
C4模型:系统上下文(System Context)、容器(Container)、组件(Component)、类(Class)
伴生系统:不是本系统的部件,但对系统的价值体现具有重要意义
系统上下文确定:利益相关者+系统范围+系统愿景
- 显示形式:业务序列图/时序图
- 通过绘制业务序列图,理清楚每件事在哪个系统发生,从而梳理出本系统与伴生系统的边界
9. 限界上下文
限界上下文:封装了特定知识的领域对象组成了领域模型,在知识语境的界定下,不同的领域对象扮演不同的角色,执行不同的业务活动,并与限界上下文内的其他非领域模型对象一起,对外提供完整的业务能力。
- 上下文其实是动态的业务流程被边界静态切分的产物
- 限界上下文之间的复用体现为对业务能力的复用,而非对知识语境边界内领域模型的复用。
限界上下文并不等于业务模块
- 业务模块并不具备独立的业务能力
- 模块的划分没有按照同一个业务变化方向进行
- 限界上下文是对目标系统架构的纵向切分,切分依据是从业务进行考虑的领域维度
限界上下文是领域驱动设计战略层面最重要、最基本的架构设计单元。
自治的架构单元四要素
- 最小完备:体现领域知识的完备性。限界上下文履行业务能力时,拥有的领域知识是完整的,无须求助其他上下文,避免不必要的模型依赖。
- 最小限制单个限界上下文的盲目扩张
- 自我履行:体现了限界上下文纵向切分业务能力的特征。由限界上下文自行决定要做什么。
- 稳定空间:要求限界上下文必须防止和减少外部变化带来的影响。通过抽象的方式降低耦合,保证访问接口的稳定性,保证内部领域模型的稳定性
- 独立进化:减少限界上下文内部变化对外界产生的影响。核心思想是封装,在边界内部形成独立的架构空间,通过菱形对称架构的网关层满足响应变化的能力
限界上下文的识别:
- 业务维度:从业务服务逆行而上,通过逐步的归类与归纳获得体现业务能力的限界上下文
- 业务知识的归类:
- 语义相关性:业务服务操作了相同或相似的对象
- 功能相关性:业务服务是否服务于同一个业务目标
- 业务知识的归纳:概括业务服务的主体特征,形成业务主体
- 业务主体的命名遵循单一职责原则,即只能代表唯一的最能体现其特征的领域概念
- 体现“高内聚”原则
- 业务主体的边界梳理
- 依据知识语境:考虑在不同的业务主体边界内,是否代表了不同的领域概念
- 业务能力的纵向切分:同一个限界上下文的业务服务应该提供统一的业务能力,服务于同一个业务目标
- 呈现限界上下文
- 业务服务图
- 业务知识的归类:
- 限界上下文的验证原则
- 正交原则:限界上下文存在正交性,指各自边界封装的业务知识不存在变化的传递性
- 正交性:两个或多个事物中的一个发生变化,不会影响其他事物,这些事物就是正交的
- 调用接口互相影响,这无法避免
- 单一抽象层次原则:保证一个方法中的所有操作都在同一个抽象层次
- 抽象层次与重要程度无关
- 奥卡姆剃刀原理:如无必要,勿增实体
- 当没有找到必须切分限界上下文的必要证据时,不要增加新的限界上下文
- 正交原则:限界上下文存在正交性,指各自边界封装的业务知识不存在变化的传递性
- 技术维度的考量
- 质量属性:不能混淆业务复杂度与技术复杂度
- 识别限界上下文时,首先考虑业务需求对边界的影响,满足业务需求之后,再考虑质量属性的影响;
- 技术因素在影响限界上下文的边界时,仍然要保证领域模型的完整性与一致性
- 复用和变化
- 运用复用原则分离出来的限界上下文往往对应支撑子领域,作为支撑功能可以同时服务于多个限界上下文
- 应对变化,体现了“单一职责原则”,即不应该存在两个引起它变化的原因
- 遗留系统:通常需要将遗留系统单独建立一个限界上下文
- 通过在遗留系统外部包装新的接口来避免其后续重构、维护等带来的影响
- 质量属性:不能混淆业务复杂度与技术复杂度
10. 上下文映射
目的:让软件模型、团队组织和通信集成之间的协作关系能够清晰呈现,为整个系统的各个领域特性团队提供一个清晰的视图
上下游区分:
- 上游:服务提供方
下游:服务调用方
通信集成模式:从技术实现角度讨论了限界上下文之间的通信集成的机制和协议
- 防腐层:位于下游,隔离上游限界上下文可能发生的变化
- 防腐层只进行隔离,不进行实际的业务实现
- 开放主机:位于上游,定义公开服务的协议(包括通信方式、传递消息的格式等)。开放主机服务更像是一种承诺,保证开放的服务不会轻易变化
- 服务行为:基于RPC通信机制的远程服务叫提供者
- 服务资源:基于REST风格定义的远程服务叫资源
- 事件:基于消息中间件通信机制定义的远程服务叫订阅者
- 共享内核:两个或多个限界上下文共享领域模型
- 好处自然是省事,开发方便
- 坏处是强耦合,违背了限界上下文“独立进化”的原则,必须保证内核非常稳定才行
- 发布语言:一种公共语言,勇于两个限界上下文之间的模型转换
- 防腐层和开放主机服务为了避免引入各自的领域模型,必须建立一层新的包装,这正是发布语言的原因
- 防腐层:位于下游,隔离上游限界上下文可能发生的变化
- 团队协作模式:将限界上下文的边界视为领域特效团队的工作边界,限界上下文之间的协作实际上展现了团队之间的协作方式
- 合作者:两个限界上下文的团队要么一起成功,要么一起失败,“同生共死”
- 强耦合,因此并不好,解决方法:
- 合并:既然强耦合,不如变成一个限界上下文
- 重新分配:将产生特性依赖的职责分配到正确的位置,移除一个方向的多余依赖
- 抽取:识别双向依赖的原因,将其从各自的限界上下文抽出,组成新的限界上下文
- 强耦合,因此并不好,解决方法:
- 客户方/供应方:一个限界上下文单向地为另一个限界上下文提供服务时
- 发布者/订阅者:概念与消息中间件的事件发布很相关,也可认为是防腐层-开放主机服务的一种特例
- 分离方式:两个限界上下文没有任何关系
- 共同的概念就需要各自重复定义,因此可以独立进化
- 遵奉者:下游完全遵从上游的模型,以消除复杂的转换逻辑
- 优点:
- 可以直接复用上游的模型;
- 减少了两个上下文之间的转换成本
- 缺点:下游强依赖上游的模型
- 优点:
- 合作者:两个限界上下文的团队要么一起成功,要么一起失败,“同生共死”
上下文映射过程的常见误区
- 习惯以语义之间的关系揣测限界上下文之间的关系
- 一个对象是否在履行某一个职责,是由它所具备的信息决定的
- 将对象的理想世界与领域模型世界混为一谈
- 领域对象之间的依赖可以仅仅通过值(而不是类型)来维持,并不要求两者间存在强依赖




