目录
案例背景
本案例是一个真实的商业案例。某企业希望构建一个课程内容管理系统(Course Content Management System,CCMS),功能如下:
-
学生通过这个系统,可以选课和学习。本专业的学生只能选择本专业的课程和通识课。
-
老师通过这个系统,可以查询和使用各种课件,制作并发布课程。如果发现课程有问题,老师可以修改课程。
-
老师可以查询本班学生的学习记录。
-
学校管理员可以审核老师发布的课程,并添加访问权限。学校管理员可以删除课程。
-
运营人员可以发布课件或课程,并根据客户订单决定向哪些客户共享哪些课件和课程。如果发现课件或课程有问题,运营人员可以修改课程。
-
内容管理员可以审核运营人员发布的课程。可以对课程进行打标签以便于用户浏览和查询。
-
超级管理员可以设置所有使用者的权限。
1战略分析
战略分析阶段对问题空间进行的梳理和分析,形成通用语言, 获取问题空间的价值需求以及业务需求。
1.1形成通用语言
通用语言就是我们经常说的术语或者数据字典。根据业务需求形成通用语言,有助于团队对事物的认知达成一致。通用语言可以通过词汇表的形式展示,其中词汇表最好还要包含术语对应的英文描述,便于研发同学在代码层面表达统一语言。示例CCMS 的统一语言词汇表如下。
通用语言和后续的领域建模是个迭代的过程,通用语言可以指导领域建模,反过来,领域建模中识别出来的业务概念进一步沉淀为企业的通用语言。
1.2价值需求分析
价值需求分析主要做的三个工作是:
1.2.1识别利益相关者
利益相关者是与目标系统存在利益关系的人、团队或组织, 可以简单理解为目标系统的用户,或与目标系统有直接交互的人、团队或组织。
本示例的利益相关者:
-
客户和用户(学校、学生、老师、学校管理员);
-
企业运营部门(运营人员、内容管理员);
-
企业IT部门(超级管理员);
-
其他:企业的管理者和股东。
1.2.2明确系统愿景
阐明目标系统要做什么,以及为何要做。可以通过商业模式、客户细分、产品定位和价值主张进行描述。
产品定位和价值主张:一站式教学平台和课程资源平台,为学校提供海量教学资源,实现教学资源共享,实现在线学习和智能化教学管理;
商业模式:
-
学校独立部署,按项目付费;
-
学校按站点方式开通账号(SAAS模式) ,按订阅付费;
-
学校单独购买课程内容,按内容付费;
客户细分:
-
大专院校;
-
高职院校。
1.2.1确定系统范围
确定系统问题空间的边界,明确系统什么该做,什么不该做。结合目标系统当前状态和未来状态进行判断。当前状态指的是系统的可用资源,包括业务资源、人力资源,资金资源等;而未来的状态则由业务目标、组织的战略规划和产品规划共同构成。
系统范围:
-
运行系统:企业内部的SAAS平台管理系统,包括客户管理,公共课程管理功能。
-
客户系统:部署在客户机房,或者通过站点形式开通的课程内容管理系统,包括校本课程管理,在线学习功能。
如果你熟悉电商业务可以把客户系统理解为商铺管理系统。本文仅对客户系统进行建模。
2战术设计
2.1领域建模
领域建模的目的是根据业务需求分析业务模型(在DDD中称为领域模型)。领域建模可以使用流程分析、业务场景、事件风暴、UML用例、四色建模等方法。
本示例采用了流程分析结合业务场景的分析方法。首先根据需求按时间轴整理出关键活动,这些关键活动可以分为5个场景,包括:
-
老师“制作课程”
-
老师“发布课程”
-
学校管理员“审核课程”
-
学生“学习课程“
-
老师对学生进行“学习评估”
2.1.1 名词建模
名词建模用于提取业务模型中的角色、业务对象组件。
领域概念中“概念”一词的含义和业务概念是相同的(注1),也就是业务中重要的、需要识别的人事物。
本示例根据流程分析和业务场景识别出来的名词如图2。
2.1.2动词建模
动词建模在DDD中用于提取业务模型中业务事件、业务服务和工件组件。
识别动词并不是为领域模型对象分配职责、定义方法,而是将识别出来的动词当做一个领域行为,然后看它是否产生了影响管理、法律或财务的过程数据、事件和规则。若存在,这些过程数据将作为领域概念放到领域分析模型中。
示例中根据名词之间的关系,可以识别出的动作包括老师“发布”课程,学校管理员“管理”课程,学生“学习”课程,学校“购买“课程库,老师“教育”学生。
过程数据:
过程数据是对企业运营和管理产生影响的数据。本示例中老师发布课程会提交“审核申请单”这个过程数据,学生学习课程会产生一个“学习记录”也属于重要的过程数据。
动词建模通过分析领域行为是否产生过程数据来找到隐藏的领域概念,弥补了名词建模的不足。
事件:
动词完成的动作可以产生触发事件。
示例中,老师“发布课程”这个行为会触发一个“审核申请单已提交”的事件。同样的,学生在“学习课程“进度达到一个阈值后,会触发一个“xx课程已完成学习”的事件,提醒老师进行查看,或触发一个记录学分的自动化任务。
规则:
规则指对行为约束的描述,可以用“若… , 就….” 描述。
示例中可提炼出“权限”规则,例如“若课程已处于发布状态,只有管理员才能删除”,“本专业的学生只能学习本专业的课程和通识课程”等。
2.1.3确认关系
根据业务需求和领域知识,判断领域概念之间是否存在关联。且对于 1:N, N:1, M:N 的关联关系,我们需要判断是否可以为这些关联关系定义一个新的类型,比如作品与读者存在 1:N 的关系,我们可以定义“订阅”这个概念来描述这种关系。
注意,我们需要尽量避免对象中的双向关系,即对象 A 关联对象 B,而对象 B 关联对象 A。当两个对象存在双向关系时,会为管理他们的生命周期带来额外的复杂度。
2.2领域设计
战略设计是在问题空间,需要考虑用户需求和业务。领域设计是在解决方案空间考虑问题,也就是说从实现和技术需求的角度考虑问题。
2.2.1识别实体和值对象
实体就是我们常说的业务对象(或领域对象),用于对业务领域中业务概念进行建模,如“商家”,“店铺”,“订单”等。实体的核心三要素:身份标识、属性和领域行为。值对象就是实体的属性。
一个领域概念到底该用值对象还是实体类型,判断依据:
-
对象的属性值是否会发生变化,如果变化了,究竟是产生一个完全不同的对象,还是维持相同的身份标识;
-
生命周期的管理。值对象无需进行生命周期管理。
2.2.2归纳抽象
本步骤中将概念类型相同的名词进行归类抽象。例如,学生、老师、学校管理员可以归为“用户”,用户的具体类型可以通过属性“角色”为其分配。同样的,对于学校这个概念,我们可以抽象为“客户”。
归纳本质上是将问题空间的业务概念映射解决方案空间的角色、业务对象和工件等组件的过程。归纳后的业务概念关系图更为精炼,如图。
2.2.3聚合
聚合就是识别限界上下文。聚合是从业务概念过渡到业务组件的一个过程。我们将按照高内聚的原则,根据领域对象之间关系的强弱来定义出聚合的边界。对象间的关系由强到弱可以分为:泛化关系,关联关系和依赖关系。
一般情况下,具有泛化关系的强相关概念可以划分到一个聚合。如本例中,客户可以分为大专院校、高职院校,用户分为老师、学生、管理员,这些都是强相关关系。
关联关系和依赖关系是否划分为一个聚合,则要根据实际情况来划分,通常需要单独的管理(有创建、增删改的需求),可以将其单独识别为一个聚合。本例中课程库包含校本课程,是一个关联关系。但课程库和校本课程都需要单独的管理,不同院系可能有其独立的课程库,个人用户也会创造自己的课程库(微盘)。对于课程,老师需要制作和发布课程,也是一个单独管理的对象,所以课程库需要划分为一个聚合。
本例中校本课程由课件组成,也是一个关联关系。老师在制作课程中需要查询和获取课件已完成课程的制作,所以课件也是需要单独管理的对象,需要划分为一个聚合。
最后我们将过程数据“学习记录”和“审核申请单”各自单独划分到一个聚合中。这些过程数据通常需要进行查询,需要作为一个数据项进行查询的我们也需要划分为一个聚合。
2.3.4设计服务
这里的服务是对应用服务、领域服务、领域行为(实体提供的方法)和端口(资源库接口、防腐层接口)的统称。
分解任务:
业务服务包含若干个组合服务,组合服务包含若干个原子服务。领域行为和端口都可以认为是原子服务。
分配职责:
-
应用服务:匹配业务服务,提供满足业务需求的服务接口。应用服务自身并不包含任何领域逻辑,仅负责协调领域模型对象,通过它们的领域能力组合完整一个完整的应用目标。
-
领域服务:匹配组合服务,包括业务对象的非原子操作(如审核,提交,发布)。控制多个聚合与端口之间的协作(如业务规则),由它来承担组合任务的执行。
-
领域行为:匹配原子服务,包括业务对象的创建、增删改。强调无状态和独立变化,由实体提供。
-
端口:匹配原子服务,抽象对外资源的访问,主要的端口包括资源库接口和防腐层接口。
本示例识别出来的服务:
课件上下文
-
获取课件-应用服务
-
课件-资源库接口
-
导入课件-领域服务
课程上下文
-
创建课程-应用服务
-
获取权限-领域服务
-
创建课程-领域行为
-
保存课程记录-资源库接口
-
修改课程-应用服务
-
获取权限-领域服务
-
修改课程-领域行为
-
保存课程记录-资源库接口
-
删除课程-应用服务
-
获取权限-领域服务
-
删除课程-领域行为
-
删除课程-资源库接口
课程库上下文
查询课程库-应用服务
用户上下文
-
创建用户-应用服务
-
获取权限-领域服务
-
创建用户-领域行为
-
保存用户记录-资源库接口
-
修改用户-应用服务
-
获取权限-领域服务
-
修改用户-领域行为
-
保存用户记录-资源库接口
-
删除用户-应用服务
-
获取权限-领域服务
-
删除用户-领域行为
-
删除用户-资源库接口
学习记录上下文
-
学生学习课程-应用服务
-
获取权限-领域服务
-
查询课程-资源库接口
-
浏览课程-领域行为
-
创建学习记录-领域行为
审核上下文
-
老师发布课程-应用服务
-
创建课程-领域行为
-
保存课程记录-资源库接口
-
提交课程-领域服务(产生审核事件)
-
管理员审核课程-应用服务
-
获取权限-领域服务
-
审核课程-领域服务
客户上下文
-
查询客户类型-应用服务
-
读取客户类型-资源库接口
End