万事开头难,需求是项目最开始的输入,肯定是非常重要的,但现实情况往往是当我们接到需求后第一个想到的问题确是我该如何实现,而没有在业务思考这一块过多的停留。如果最开始理解的输入是错误的,后面的过程再优秀可想而知也只能是垃圾。为了解决这一问题,很多优秀的大佬发明了很多对需求进行功能建模的工具,主要目的就是让我们更好的理解需求并认识其背后的本质。如常用的工具有5w2h、业务活动、用户旅程、商业画布等。这些在网上都有很多的资料,只举几个例子,不做重点介绍。

在我们日常工作的项目中,大多数场景都可以通过在需求用例中通过找名称的方式来最终刻画出领域模型,当然找到的名词后并不是所有的都符合要求,这时可以通过一条原则"一个名词或实体必有其属性和行为,一属性或行为也必归属于一个实体"来进行提炼,不符合这条原则的名词就是需求剔除的。总体来说建模一共分为四步

选名词:从用例中选出所有名词,在去伪存真选出符合要求的;
找动词:找出所有动词,在判断这些动词属不属于上一步选出的名词所具有的行为;
加属性:找出所有属性,在判断这些属性属不属于上一步选出的名词所具有的特征;
连关系:确定实体和实体之间的协作关系;

案例:用户购买商品

第一步: 选名词 。从用例上选的名词如下:用户、购物app、商品、用户档案、用户名称、地址、商家、订单、子订单、支付方式、银行卡、支付宝、微信。通过这种方式可以很轻松的识别领域中的相关概念,但选取的名词并不一定都是领域相关的,所以接下来还需要进一步的提炼。提炼过程

删除"购物app":购物app只是一个功能的载体,并不属于购买商品流量里的一个领域概念,所以删掉
删除"用户名称" :用户名称只是用户的一个属性,并不是领域概念
删除"地址" :地址只是用户档案的一个属性,并不是领域概念
删除"银行卡、支付宝、微信、支付方式":银行卡、支付宝、微信属于支付方式的一种具体形式,而支付方式可以归属为订单的一个属性,并不是独立的领域概念

所以最终提取的领域实体是:用户、商品、用户档案、子订单、订单、商家

第二步: 找动词 。从用例上选的动词如下:选取、汇总、下单、保存、支付、取消

找动词的目的是反向检查是否有遗漏的实体没有提炼出来,因为有些隐含的概念并不一定能在用例里找到,且一个动作必归属于一个实体。如果有发现动作没有归属实体只有2种情况,一是这个动作不属于这个领域,二是有遗漏的实体没有提取出来。经过分析 "选取" 是用户主观的一种行为,并不属于这个领域所以删掉,"下单、汇总、保存、支付、取消" 都属于订单的动作。

第三步: 加属性 。理论上产品同学要在用例上把模型的所有属性全部列出来,但现实情况不一定能做到,这时除了用例还需要当面和产品对焦清楚各个模型的属性。

归类分组,就是把具有相似性或相关联的信息,按照一定的标准进行分类,归为同一个逻辑范畴。“类”是一个极其重要的概念,可以看作本质相同或相似的事物的集合。分类就是按照一定的标准,根据对象属性、特征的共同点和不同点,将对象划分为不同的种类。分类时,需要对这些类别进行鉴定、描述和命名。

分类在生活中无处不在。通过分类,一方面可以把杂乱无序的事物区分开来;另一方面还要赋予不同类别以稳定的、概念化的名称。一个好的命名,能够简洁有力地表述事物的本质。分类的过程,就是探寻事物和问题本质的过程。

如何用归类分组进行领域建模可以分为3个步骤

第一步:定义要建模的领域问题:也就是要清楚我们要解决的问题是什么?

第二步:对领域问题进行拆解:对问题进行分析拆解,形成平铺的多个子问题,此步骤可以尽量发散

第三步:归类分组:对子问题进行归类,剪枝,将趋同的子问题,合并成一类(可以理解问产出实体)

案例:生活服务类商品

生活服务类商品场景

预定类商品(KTV预定、休娱预定、丽人预定等):
第一步:定义要建模的领域问题:从上面的售卖商品场景可以看出一个商品有多个价格;而决定这个价格的是由一系列的因子决定的,有可能是0个也可能是多个;如何用一套完备的价格模型来支持这些场景是需要解决的问题;
第二步:对领域问题进行拆解:罗列出所有商品价格的场景;

为什么引入事件风暴。 事件风暴之一的作用就是拉通业务方、产品、研发、测试对业务知识的统一理解,避免各方理解误差。但在实际操作中受限于各方时间协调的难度及领域专家的角色的缺失,事件风暴往往作为理解业务,领域建模及领域划分的利器去使用。

什么是事件风暴。 事件风暴是一种以工作坊的方式对复杂业务领域进行探索的高效协作方法,事件风暴强调以事件驱动团队探索分析业务领域。

一种捕获行为需求的方法

强调以先发散后收敛的方式开展

相关干系人协作的方式进行

注重对领域事件的识别

事件风暴相关元素

事件:重要且已发生的事情。命名方式:完成时+被动语态=宾语+动词过去式

命令:产生事件触发的动作

角色/执行者:触发命令的主体,包括:人员、系统、定时任务

读模型:执行者决策执行命令时参考的视图元素

事件风暴操作流程

识别重要事件

识别执行者和读模型

识别领域对象

产出领域模型

案例:销售基础

识别重要事件

关于四色建模的概念我们可与追溯到90年代,是被广泛使用的一种系统分析方法。四色建模的目的是要对目标业务系统进行分析并通过不同的颜色标示出人,事,物,角色,通过四色建模得到四色原型图,每个原型图有属性和连接(关联与依赖等关系)两个部分组成。

那四色原型具体是哪四色呢?一起来看看

时标原型(Moment-Interval Archetype,简称MI)

用一句话来概括四色原型就是: 一个什么样的人或物品以某种角色在某个时刻或某段时间内参与某个活动。其中“什么样的”就是DESC,“人或物品”就是PPT,”角色”就是ROLE,而“某个时刻或某个时间段内的某个活动”就是MI。

接下来使用四色建模法来分析领域模型,总共分为四大步:

建立时标原型: 寻找需要追溯的事件,根据追溯事件寻找足迹

建立PPT原型: 丰富模型,寻找时标原型周围的人/事/物,使它可以更好地描述业务概念

建立角色原型: 进一步从中抽象出可以参与到不同流程中去的角色

建立描述原型: 把一些信息用描述对象补足

案例:商家咨询

梳理咨询业务时序 ,任何的业务事件都会以某种数据的形式留下足迹。我们对于事件的追溯可以通过对数据的追溯来完成,当我们把这些数据的足迹按照时间顺序排列起来,就可以清晰的推测出过往的一段时间内发生的事情。

通过对业务的梳理可以产出了四色原型图的关键业务时刻,如下面表格

限界笔纸法起源于thoughtworks,由thoughtworks大佬提出的基于四色建模的改进方法。在“四色建模法”的“时标对象”的基础上确定"限界上下文”与“聚集”的概念,再使用“纸和笔来管理”的方法,力图在建模过程中实现“分而治之”,增强数据的完整性,并避免过度设计。

根据“业务发生时刻”的价值识别核心领域(core domain)

确定核心领域之间的依赖关系

用纸和笔画表格并写实例(这里的实例可以是业务用例,用户故事,或者业务发生时刻)

确定“聚合根 (AGGREGATE ROOT)”

以“人以群分”的原则抽取新的“聚合”

经过领域模型的分析后,面向对象已经初具雏形,但领域类并不能指导我们进行编码工作,因为领域类只是从用例模型中提炼出来的反映业务领域的概念,并不是真正意义上的软件类,我们要需要在进一步,完成领域类到软件类的转换,这就是代码建模阶段的主要任务。那么具体如何做的

第一步:完成领域类到代码类的映射
领域模型是生活中模型的映射。 在几十年前,我们没有计算机,但是我们仍然可以通过白纸黑字的方式完成我们的业务。换句话说,我们的业务系统只是把一个纸质的单据变成了电脑里存在数据库里的东西。也就是说,我们的模型,一定是在生活中有实际的对应的单据,而且名字也应该是一致的。千万不要臆造概念。
领域模型不是DB模型。 领域模型不是DB模型,一个领域对象可以有多种方式映射到数据库,但是我们聊领域模型的时候,一定不是聊DB模型,重要的一定是描述清楚业务概念。在做ORM的时候,如果有继承关系需要的实现的时候,我们再考虑是单表继承(Single Table Inheritance)还是实体表(Concrete Table Inheritance)等模式。
领域模型的关系一定是稳定的。 当接到一个新的需求时,如果发现模型的关系不匹配了,那说明之前的模型设计的肯定存在问题,好的模型实体和实体之间的关系一定是稳定的,只会新增不会对原有关系进行改变。

要在"变化的现实世界中寻找不变性",希望寻找到一个稳定的领域模型,让系统流程可以灵活改变,模型不怎么变,但在实际中却很难完美的做到,这是为什么呢?(备注:这里的迭代不是指对原有模型关系的重构,而是对模型新关系的升级)

意识问题。在用户、产品人员、运营人员眼中,沟通的语音是"流程"而不是"模型"。开发人员在与他们的沟通过程中,慢慢就形成了以"流程"为主导,而不是以"模型"为主导的思维方式。这使得整个开发过程是"流程驱动",而不是"领域驱动"。大家在讨论业务与系统解决方案的时候,大部分时间都花在了业务流程、业务规则上,而不是深刻挖掘流程背后的不变因素。
现实世界的复杂性。业务也就是我们的现实世界,灰度的、模棱两可的东西,比计算机的世界多得多,变化也多得多。很难确定有哪些东西是不怎么变的,什么东西是容易变的,而这恰恰是做建模的前提条件。
迭代速度。在稳固的模型,也不可能一成不变,毕竟现实世界一直在变。当现实世界变化到模型不能支撑的时候,要能马上修改模型才行。但实际情况是,因为开发效率的原因,工期赶不上,然后就会在旧的模型上进行打补丁,补丁一个接着一个打,最后整个系统臃肿不堪,开发效率进一步降低,如此恶性循环。

火候的掌握。领域模型是要对现实世界建模,既要去寻找不变性,又要为可能变化的地方留出扩展性。什么地方是不变的,要作为基础;什么地方是易变的,要留出扩展性,这其中并没有一个标准原则。另外,各家公司的业务规模、速度不一样,团队实施能力也不一样。所以在实践中,要么会"缺乏设计",要么会"过度设计"。对火候的掌握,需要有悟性。只有反复思考,反复推翻自己之前的想法,再重建新的想法,才能在实践中不断找到领域模型、业务发展速度、技术团队能力之间的"最佳平衡点"。