DDD的应用实践是一个认知的过程,在实践时团队成员尽量保持同一水平的认知,通俗来说,就是错也要错的一致,同时在落地时要以多数人的认知为基准实施,不能以认知程度高的少数人标准来落地。
初学者可以按本节精炼战略和战术的核心内容先实践。本节中提到的知识点会在后续章节详细展开。概念和术语会随章节内容逐个介绍。在开始之前有必要先澄清两个概念,以免造成混淆:
在设计开始之前,我们先虚构一个简单的协同系统,此协同系统采用scrum管理方式,采用传统的scrum模型,主要包括:Product(产品)、Release Plan(发布计划)、Backlogitem(待办项)、sprint(冲刺项)、Team(负责团队)、Product Owner(产品负责人)、Task(任务)、Priorit(优先级),业务模型经过初步分析后,如下图所示:
业务规则大概如下:
下面我们就以这个虚构的业务案例为背景,看下DDD是如何应用到软件系统设计中的。由于DDD中的概念和规则还是挺多的,所以在每节的开头会先解释下DDD中相关的术语,然后再以本案例进行分析,读者也可以先按照DDD的概念分析本案例,最后对比笔者的分析,可能会达到事半功倍的效果。
DDD中的战略主体是业务,并不是由公司经营者制定的以运营或管理为目的的那种战略规划。详细来讲是指以业务为核心,合理的设计模型(领域)、划分(限界上下文),再综合组织架构、技术等因素辅以相应的集成策略(上下文映射)。
以公司运营为目的的战略规划虽不是DDD的设计范畴,但在DDD战略设计时需要参考公司战略、组织架构等因素,因为这些因素会影响两个上下文映射时的策略选择,后面章节会详细讲述。 |
---|
上面的术语经过解释后还是会比较抽象,举一个例子可能会更好的理解一些,比如一个只包含用户管理、角色管理、资源管理(url菜单)三个模块的简单权限管理系统,套用上面的术语可以表述为: 1、 在权限管理系统中,包含用户、资源、角色三个限界上下文;2、在用户限界上下文中包含用户域;3、在用户域中包含用户组、用户两个模型,在角色域中包含角色、用户两个模型; 注意”用户”出现在了两个域中,但业务含义是不一样的。在用户域中多指真实存在的人或系统,关注用户身份、密码等属性,在角色域中的用户一般是指系统的操作者,一般只需关注用户标识即可。 |
---|
注意”用户”出现在了两个域中,但业务含义是不一样的。在用户域中多指真实存在的人或系统,关注用户身份、密码等属性,在角色域中的用户一般是指系统的操作者,一般只需关注用户标识即可。
从业务上划分模型的职责和边界,传统模式下业务模型一般会以E-R图、数据模型图或是图+表的方式来表述,关注点通常是实体属性、数据导航等,然后把模型划分到不同的系统模块中来表述隔离,如下图所示(图中的M指模型是Model的缩写):
实际上系统模块并不适合做为业务模型间隔离的依据,严格来讲系统模块本质上更趋向于终端应用界面的展现、模型才是是业务的映射,模型间的隔离也需要从业务角度来划分会更为合适。因此系统模块和业务模型本质上是没有直接关系的。本节中所说的上下文划分正好弥补了上述设计过程中的不足,下图展示的是限界上下文划分的过程,左下方框内是拆分后的限界上下文。
一般会先先识别出核心业务,然后再丰富模型。上图中最左侧是去掉模块后的传统业务模型,蓝色的三个步骤是建议的限界上下文的拆分过程,每一步的过程及要点如下:
经过分析后,协同系统的模型拆分如下:
用业务术语命名模型,拉齐认知,方便团队沟通。当限界上下文划分完成后,我们有必要全部重新审视一次,就好比考试答完试题后的复查,并用下面的表格记录所有提炼出来的业务短语,并在全团队范围内明确。软件最终交付的是代码,但交付不了知识。但在迭代过程中需要把知识传递下去,可以把通用语言看作知识传递的方式,可视化的表格就是这种知识的载体,建议用excel表格即可,最好是在线的那种。
通用语言 | 类型 | 所属限界上下文 | 详细说明或场景描述 |
---|---|---|---|
Scrum上下文 | 上下文 | Scrum上下文 | scrum管理 |
product | 模型 | Scrum上下文 | 指用于敏捷开发的产品 |
SprintItem | 模型 | Scrum上下文 | 产品负责人可以提交位于发布讲中的待办项到冲刺中,如果待办项已在另一个冲刺中,那么需要先回收。(event)当待办项提交完成后,需要通知相关冲刺方; |
…… | …… | …… | ………… |
通用语言模型在不同的上下文中才有意义,所以不建议创建全局唯一的通用语言;上下文和通用语言是紧密联系在一起,不能脱离开上下文只说通用语言;不同上下文中可以存在名称相同的通用短语,多数情况下也是同一个模型,区别在于关注点不一样,比如在团队管理上下文中关注的用户唯一标识信息,而在scrum上下文中关注的责任人或负责任务开发的人员名称,并不关注用户标识 |
---|
定义价值,DDD战略是通过业务价值分析划分领域类型进而制定战略的。子域划分除了可以识别出对组织最有价值的模型,同时也可为系统建设在优先级、投资规模、架构设计、产品定位等一系列活动过程中提供决策依据。DDD中的域可以分三类:
经过分析后,此时应该会有多个限界上下文,其中之一必定会成为核心域,而其它的则成为支撑域或通用域。我们用绿色表示核心域、黄色表示通用域、粉色表现支撑域。经过分析后,协同系统的上下文划分如下图所示:
域、限界上下文和模型:这三者可以看做是顺序包含的关系,但是建议一个上下文只包含一个子域而且要尽量保持,实际上允许的一个上下文中包含多个子域,但是容易造成模糊,同时需要用辅助文字来解释。如果遇到一个上下文中多个子域时,更建议用模块来代替子域,即一个上下文由多个模块组成,每个模块对应一个子域。 |
---|
制定上下文间集成策略,这是战略设计的最后一步。前面我们已经按内聚性、不变性、价值等维度划分了业务模型,本质上业务运行过程中是少不了任何一个模型的。这一步我们需要再把他们联系起来。DDD中用下图所示方法表示,如果需要关联,则在两个椭圆间画一条不带简单的实线,线上标识U和D,U表示上流,D表示下游。
注意,这里的上下游关系并非应用间API接口调用的表述,而是纯粹的业务映射,比如订scrum上下文必须依赖团队管理上下文。同时这个映射关系有时需要考虑组织架构的影响,比如由两个团队负责开发协同系统,负责团队管理应用的团队就是不提供API接口给Scrum团队,虽说业务上依赖,但在这种情况下scrum团队就需要重新考量了,是组织升级还是自建。
在业务模式不变的前提下,上下文映射策略是会发生变化的,但领域模型是不会变化的 |
---|
在DDD共总结了8种映射策略,本小节先介绍两种常见的映射策略,其它的会在后续章节详细展开:
经过分析的,协同办公的上下文映射如下图:
软件系统实质上是一种IT技术的编码实现,在战略设计过程中除了考虑业务、业务价值、组织架构等因素,个人认为是有必要加入技术考量的。
比如:在应用集成时,上游团队提供的接口有可能是Soap、Restful、Mq、SDK等多种形式,相对来讲,同样复杂度的服务不同协议类型的接口性能是不一样的。如果我们的业务对性能、安全有要求,在上下文映射时就需要考虑技术因素。下图是一个简单示例(PL=已发布语言、OHS=开放主机服务、ACL=防腐层):
在讲述上下文映射集成和架构设计时会详细展开技术集成的细节内容 |
---|
补充后的上下文映射如下图所示:
输出物 | 类型 | 说明 |
---|---|---|
上下文映射图 | 图型 | 见节:第四步、上下文映射图或第五步、补充上下文映射图 |
通用语言描述表 | Excel表格 | 见节:第二页、提炼精炼语言中的表格 |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。