领域建模的方法

一、领域建模的好处

DDD最大的好处是:接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。DDD强调业务抽象和面向对象编程,而不是过程式业务逻辑实现。重点不同导致编程世界观不同。面向对象

  • 封装:Account的相关操作都封装在Account Entity上,提高了内聚性和可重用性。
  • 多态:采用策略模式的OverdraftPolicy(多态的典型应用)提高了代码的可扩展性。

二、如何进行领域建模

其实就是如何识别领域,找到需要建模的领域有哪些,这里有六个方法:

2.1 业务流程:

模型是客观存在的,只是你能不能把它画出来。要画出领域模型,它的方法是从业务流程入手,没有找到业务流程很难画出领域模型(不管你用什么方法,虽然叫法不一样,实施流程不一样,但有些本质思路是一样的,这个大家可以自行体会)。所以,画一个领域模型时,不管通过什么途径找出其业务流程。任何业务都存在一条稳定的业务流程。

在找到业务流程后,比如优惠券业务,其流程是建券、发券、用券,每个流程都会有产物,建券的产物就是券模板(券批次),发券的产物就是券实例,所以这里的产物就是整个业务骨架,这和四色建模中的时序对象一样,综合了四色建模和事件风暴的方法。

  1. 找出业务主流程:第一步是找出业务主流程,这是业务的生命周期,不管怎么讲,任何业务都有一套稳定的业务流程。当接手一个新业务时,先不要急着想领域模型,当按照我分享的步骤去分析业务时,领域建模自然会水到渠成展示出来的。类似上面的优惠券业务,业务流程就是建券、发券、用券。业务主流程每个流程节点都会有一个产物出现,这个产物就是业务的骨架,在这个业务下,它的产物是券批次、优惠券实例。注意,它仅仅是一个骨架,但至少找到两个关键领域对象。

  2. 细分业务主流程:这一步是在主流程基础上继续分析子流程,主流程能让我们知道整体的业务流程,但还有些细节流程是在子流程中,比如建券是一个大流程,那么我们马上会问,这个券长什么样?有哪些关键属性?等,是不是多问几个为什么马上让我们就深入到业务细节了。再比如发券过程,需要经过一些检查,如规则检查、风控检查,最后才是发券,这样分析下来,我们对业务掌握得越来越深入。上面提到我们分析出的两个关键领域对象,此时再从两个方面考虑:一个是其它对象关联,或者包含券模板和优惠券实例;另一个是券模板或者优惠券实例包含其它。

  3. 抽象:从第二步中,我们得到更多具体对象,但此时要进行合并整理,并不是直接加到券模板或者优惠券实例关联部分上,这个过程是不断打磨的过程。上面就是领域建模的三步方法:找出业务主流程、细分业务主流程、抽象。没有任何高深的理论、简单朴素的方法,至于为什么觉得简单,是因为前期铺垫唤醒了你之前的经历,再去做相似的事就会觉得有熟悉感。

具体看:https://www.infoq.cn/article/6hpbsmxqngx_eapkuuws

2.2 用例建模

  1. 识别业务执行者:业务执行者(businessactor)是在系统之外与业务交互的人或组织;业务工人(businessworker)是在系统内帮助完成业务处理的服务人员或系统。一般来说,真正的顾客才是业务系统的执行者,如银行贷款系统的业务执行者为来银行办理贷款业务的客户。

  2. 识别业务用例:业务用例是业务单元为业务执行者提供的完整价值,需要从业务执行者的角度对每一个业务单元进行分析提取业务用例。UML 用例图主要由业务用例和业务执行者构成,通过“业务执行者——业务用例”的模式来反映业务执行者驱动业务用例的状况。

  3. 描述业务用例:对业务用例的描述是为了说明各业务用例的实现过程。业务用例的描述有两种方式:用例文档和UML动态图:如序列图或活动图。采用用例文档来描述业务用例需要遵循一个用例模板,该模板中一般应包括以下信息:用例名称、用例编号、用例的简短描述、用例的业务执行者、业务工人、前置条件、后置条件、用例的输入、输出、用例的执行过程等。

  4. 分析方法提取类:依据用例描述文档找出其中所有的名词,将名词作为类和对象的候选者。

  5. 定义类的属性和行为:属性是类的一个描述特征,类的行为描述了这个类在系统中所提供的服务。和类的来源一样,类的属性和行为也有一部分来源于用例描述文档。文档中的形容词作为确定类的属性的线索,动词作为类行为(操作)的候选者。

  6. 建立类之间的关系:找出实体类,确定了类的属性和行为以后,还需要分析任意两个类之间的关系。类之间的关系主要有四种:泛化、关联、聚合、依赖。

具体参考:https://www.cnblogs.com/silviayun/p/11884645.html

2.3 事件风暴

事件风暴是一项团队活动,领域专家与项目团队通过头脑风暴的形式,罗列出领域中所有的领域事件,整合之后形成最终的领域事件集合,然后对每一个事件,标注出导致该事件的命令,再为每一个事件标注出命令发起方的角色。命令可以是用户发起,也可以是第三方系统调用或者定时器触发等,最后对事件进行分类,整理出实体、聚合、聚合根以及限界上下文。在整个事件风暴方法中,有三个关键要素如下:

事件 -> 某个动作的结果
命令 -> 某个动作
实体 -> 命令的触发者

而整个分析流程可以简单总结为:首先是基于业务分析来识别关于的事件,同时识别和梳理出事件对应的命令,在事件和命令中都会附带有对应的领域对象和实体,因此进一步基于对象实体进行命令和事件的聚合。在完成聚合后再进一步梳理和划分上下文界限。网上有篇文章举了一个完整的例子大家可以参考:https://www.jianshu.com/p/96801c93a47d

  1. 识别事件和命令:事件你可以理解为一个事物所编写出来的最终状态,例如订单已创建,支付已完成,商品已发货等即是关键的事件。而命令可以理解为具体的业务功能或操作,比如创建订单,检索商品,扣减库存等。可以看到事件和命令的识别和分析中,都可以识别到具体的领域对象。

  2. 基于领域对象进行聚合:如何进行聚合?简单来说仍然是通过识别和梳理出来的共性领域对象进行聚合。将对同一领域对象的所有命令和事件都聚合在一期。

  3. 进行上下文边界的划分:基于聚合完成的情况进行上下文边界的划分,这里实际上不同的领域对象如果属于同一个大类的业务场景,仍然是可以划分到一个上下文里面的。也就是不是简单的按聚合完成的领域对象划分上下文边界,很多和核心领域对象相关的附属对象也需要划分到同一个上下文的。比如电商里面的订单是一个大量的领域对象,可以划分为独立的上下文,但是对应购物车也是我们识别的对象,购物车本身同样属于产品订购场景,订单的扩展附属对象,因此需要将购物车也划分到订单上下文里面。

具体看:http://dockone.io/article/1904916,https://hanchenhao.github.io/MadBOK/DomainDrivenDesign/11-%E9%A2%86%E5%9F%9F%E5%BB%BA%E6%A8%A1%E4%B8%8E%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4.html#%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4%E8%A6%81%E5%87%86%E5%A4%87%E7%9A%84%E6%9D%90%E6%96%99

2.4 四色建模

四色建模法包括:时标型(Moment-Interval)对象;PPT(Party/Place/Thing)对象;角色(Role)对象;描述(Description)对象,我们建模的次序和重点:

首先以满足管理和运营的需要为前提,寻找需要追溯的事件。
根据这些需要追溯,寻找足迹以及相应的时标性对象。
寻找时标对象周围的人/事/物
从中抽象角色
把一些信息用描述对象补足。

由于在第一步中,我们就将管理和运营目标做为建模的出发点。因此,整套模型实际上是围绕这些“如何有效地追踪这些目标”而建立的,这样的模型可以保证模型支撑企业的运营。四色建模法通过将管理和运营目标做为建模的出发点,整套模型实际上是围绕这些“如何有效地追踪这些目标”而建立的,这样的模型可以保证模型支撑企业的运营,四色建模法和别的建模方法相比,更倾向于作为一种分析方法,而不是设计方法,通过将分析得到的领域对象分别归入这四类原型,能让我们更加深刻的理解每个对象的职责,以及对象之间的相互关系。

http://apframework.com/2020/03/22/ddd-color/
https://www.infoq.cn/article/xh-four-color-modeling
https://blog.csdn.net/weixin_44295717/article/details/111394824
http://dockone.io/article/989230

2.5 找名词

一个关键的问题还没有说明:从哪里找?如果你还记得领域模型是“需求到面向对象的桥梁”,那么你肯定一下子就能想到:从需求模型中找,具体来说就是从用例中找。归纳一下域建模的方法就是“从用例中找名词”。当然,找到名词后,为了能够更加符合面向对象的要求和特点,我们还需要对这些名词进一步完善,这就 是接下来的步骤:加属性,连关系! 最后我们总结出领域建模的三字经方法:找名词、加属性、连关系。

  1. 发现类和对象:尽可能多的找出概念类(识别方法:概念类分类列表、名词性短语)。概念分类列表:人、事物、地点、组织、概念、事件、规则、抽象名词、交易项目、角色、设备、组织结构(对用例进行识别:实体、过程中的信息、角色的输入输出、操作设备等);名词分析法:识别问题域和用例描述中的名词和名词性短语作为候选的概念类和属性,从候选项中,摒弃多余的名词,确定最终的对象(注意是作为类还是属性,类可以是一种标识、状态和行为)

  2. 建立类之间的关联(关联、继承、依赖)。关联:类之间的某种语义关系包括聚合,组合;继承:一般到特殊;依赖:表明一个元素(源元素)的定义或实现依赖另一个元素(被依赖元素)的定义或实现

  3. 添加类的重要属性(类的语义完整性、类的作用、问题域相关特性等)。语法:可见性 属性名:类型 多重性=默认值{特性表}/ [可见性] 属性名 [:类型] [=初始值];属性类型是简单的数据类型为佳,如果是复杂概念,考虑是否单独作为一个概念类;任何属性都不表示外键,即不应该用属性来联系概念类,区别于数据库设计中的外键

具体看:https://www.cnblogs.com/silviayun/p/11884645.html

2.6 领域驱动建模(DDD)

DDD建模的一般步骤:

  1. 构建领域知识:软件的最终目的是增进一个特定的领域。为了达到这个目的,软件需要跟要它服务的领域”和谐相处”。所谓和谐相处,软件需要精确地反应领域概念和知识,以更好的适应变化。因此,软件开发者第一步也是最重要的一步就是理解领域知识。DDD鼓励开发者和领域专家工作在一起,通过交谈和提问,让开发者学习到领域知识,挖掘出领域的关键概念。

  2. 创建通用语言:通用语言是领域专家和开发团队之间定义的标准的术语。目的是把领域知识更完善地传达到软件中。团队在进行所有方式的沟通时(文字,演讲,图形)都需要采用这种一致的语言。通用语言需要映射到模型中,映射到代码里。做到通用语言的更改就是对模型的更改,也是对代码的更改。

  3. 创建实体:基于通用语言和领域知识,需要首先分辨出实体。实体是领域中需要唯一标识的领域概念。如果两个实体所有状态都一样,但标识不一样,就是两个不同的实体。实体同样需要属性来描述

  4. 创建值对象:值对象是领域中不需要唯一标识的领域概念。如果两份对象所有状态都一样,我们就认为是同一个值对象。值对象也可以理解为一组聚合的属性。例如地址信息,类目信息。

具体看:http://www.fanyilun.me/2018/04/08/%E8%B0%88%E8%B0%88%E9%A2%86%E5%9F%9F%E5%BB%BA%E6%A8%A1/

三、战略建模和战术建模

战略建模和战术建模,其实是《实现领域驱动设计》最前面的内容,位于《如何使用本书》部分,当时看的时候并没有很注意,但在前两章的内容中,发现有很多这样的字眼:“团队有人花额外的时间去了解战术模式、团队采用的是战略模式的建模方式。。。”,这就不得不让你回过头看下,什么是战略建模和战术建模?其实,关于这两点,作者并没有很准确的进行定义,只是分别描述了这两点内容的关键字,我们来总结一下:

战略建模:界限上下文(Bounded Context)、上下文映射图(Context Mapping)。
战术建模:聚合(Aggregate)、实体(Entity)、值对象(Value Objects)、资源库(Repository)、领域服务(Domain Services)、领域事件(Domain Events)、模块(Modules)。

具体看:https://developer.aliyun.com/article/381086

3.1 战略建模

限界上下文:它是一个限定边界的环境,在该环境中,每一个模型的概念(包括它的属性和操作)都具有特殊的含义。它是战略建模的核心,在每一个限界上下文里都共用且只有一套通用语言,不存在二义性。。在确定子域及限界上下文后,一些容易混淆的概念会逐渐得到清晰的描述,这样可以方便开发团队、业务人员及客户之间的交流,而且还为我们开发时划分项目功能提供最直接的依据。

而上下文映射图:通用使用框图或代码的方式来展现限界上下文之间的集成关系。实线连接,表示两端的限界上下文之间存在联系。线上标注的U/D表示上游/下游。通常情况下:上游的限界上下文会为下游提供访问接口(或服务),下游使用一个防腐层获取从上游接口传过来的数据,然后转化成本限界中使用的实体。

具体看:https://www.cnblogs.com/yubaolee/p/4552646.html

3.2 战术建模

这里边有具体的战略和战术建模的例子:https://tech.youzan.com/joker-ddd/

四、总结

回过头来看以上六个方法在战略和战术建模中其实都是有应用,但是在建模过程中,还是要顺着战略和战术的思路去构建,这样才能做出来一个好的设计。DDD是领域驱动设计,而不是领域驱动开发,所以我们在开发的时候具体采用哪一套开发流程,又是另外一套说法了。

猜你喜欢

转载自blog.csdn.net/maoyeqiu/article/details/121416404