领域模型

领域模型是对领域内的概念类或现实世界中对象的可视化表示。又称概念模型、领域对象模型、分析对象模型。它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。

学会了面向对象的思想,却依然写不出好的面向对象的程序,下面我从“领域建模”这个单点要素,谈一下自己的体会,如何从需求分析到面向对象设计这样一个过程,以及互联网最近比较火的架构(微服务、中台)是怎么一步步演变而来的。以下 我所说的可能都是错的,只是一家之见,欢迎大家在留言区多提意见和看法,互相共勉。

什么是领域模型

1、 领域模型

领域模型(Domain Model),是完成从需求分析到面向对象设计的一座桥梁,领域模型是指对需求所涉及的领域的建模,所以 也叫业务对象模型,是描述业务用例实现的对象模型。它是对业务角色和业务实体之间应该如何联系和协作以执行业务的一种抽象。业务对象模型从业务角色内部的观点定义了业务用例。该模型为产生预期效果确定了业务人员以及他们处理和使用的对象(“业务类和对象”)之间应该具有的静态和动态关系。它注重业务中承担的角色及其当前职责。这些模型类的对象组合在一起可以执行所有的业务用例 。

2、对象

当研究参与业务中不同用例的业务角色和业务实体时,可能会发现某些对象如此相似,以致于实际上是一个类,即使不同的业务用例没有相同的要求,类是这些 不同的业务用例 之间也可能相似到足以被视为一个相同现象的程度,如果是这种情况,应该将相似的类合并在一起,这时就产生了一个业务角色或业务实体,它拥有足以满足不同业务用例要求的关系、属性和操作。

3、模型

在业务对象模型中,业务角色代表雇员将担当的角色,而业务实体则代表雇员将处理的对象。一方面,可以使用业务对象模型来确定业务雇员将如何进行交互,以产生业务主角所期望的结果。

Model对于数据处理是最核心的东西,数据模型是数据组织和存储方法,模型的好坏,决定了数据库或者数仓能支撑企业业务多久。 为什么大多数企业, 数据库或者 数仓都要重建,这不仅仅是业务拓展、发展迅速,很大一部分是因为模型建的很烂。

不同维度对领域模型的理解

领域建模, 从领域模型开始,我们就开始了面向对象的分析和设计过程,就是建立最重要的业务概念和它们之间关系,是真实世界各个事物的表示(现实世界的可视化抽象字典)而不是软件中各构件的表示。类,表示业务概念,通常只包含重要属性,甚至不包含操作;关联、泛化,表达概念之间的关系,可以说领域模型是描述业务领域(业务实体)的静态结构。

1、业务

领域模型是一种特殊的业务模型,它分析范围是整个行业,抽象出行业里共性和内在规律性的业务,比业务模型更加抽象,它不属于软件开发范畴的概念,与软件开发无关。

(1)Domain Model是一个商业建模范畴概念,即使一个企业不开发软件,也具备其业务模型;

(2)所有同行企业,其业务模型必定有非常大的共性和内在的规律性。

(3)由行业内的各个企业的业务模型再向上抽象出整个行业的业务模型,这个模型称之为“领域模型”。

2、软件

领域模型是一种分析模型,在软件开发过程分析阶段用于分析如何满足系统功能性需求,属于软件开发范畴,在UML中主要使用类图来描述领域模型,帮助系统分析人员、用户认识现实业务的工具,描述的是业务中涉及到的实体及其相互之间的关系,它是需求分析的产物,与问题域相关。

(1)是需求分析人员与用户交流的有力工具,是彼此交流的语言;

(2)业务模型是业务建模的输出物,业务建模研究的对象是公司或者组织,业务建模属于软件开发过程中的初始阶段;

(3)软件开发过程:业务建模、需求、分析、设计。

领域模型的作用

软件的核心是解决领域问题的能力,这是软件存在的本质价值;软件开发团队必须掌握领域知识,才能开发出能够解决领域问题的有价值的软件,然而领域模型是对领域相关知识的选择性抽象和严格的组织,一个合适的模型能够帮助开发团队理解信息的涵义和聚焦于问题本身,同时和实现紧密联系。

1、发掘重要的业务领域概念

(1)领域模型用于捕获系统语境中的一些重要领域对象类,一般是以类图表达的。

(2)业务模型是用于在系统开发中捕获业务处理和其中的业务对象。

2、建立业务领域概念之间的关系  ,即连关系找出领域对象之间的关系。

3、领域模型与软件设计核心的相互塑性

领域模型与实现是紧密联系并相关的,这保证了对领域模型的讨论分析能够作用于最终产品--可以运行的软件;同时也可以根据领域模型来解释代码,对软件的维护和继续开发也很有帮助。

4、领域模型是团队所有成员所使用的语言的核心

因为领域模型是团队在组织领域知识和辨别最感兴趣的原理时达成一致的方式,设计人员、开发人员和领域专家将共用的信息放在领域模型这种形式中,开发人员可以用领域模型来讨论程序,能够和领域专家在没有翻译的情况下交流,,可以使他们在合作时更高效。

如何领域建模

领域建模的方法就是从需求模型中找,具体来说就是从用例中找名词。对通用语言中名词、动词的使用需要认真考量,因为这些名词和动词会作为后面模型的指导命名,名词在一个限界上下文(bounded context)中不能存在二义性。当然找到名词之后,为了能够更加符合面向对象的要求和特点,我们还需要对这些名词进一步完善,这就是接下来的步骤:加属性、连关系!

1、找名词

按照领域专家的说法就是将用例中涉及到的名词仔细的找出来后,列成一个清单,方便进行进一步的筛选,删除掉不是领域对象的名词。哪些不是领域对象的名词?这个是和不同的业务领域强相关的,这个没有统一的标准,筛选的好坏跟经验与知识有很大的关系,其中一点,和用例模型有关联或有交互的即为领域对象。

按照软件开发的说法就是发现类和对象:尽可能多的找出概念类(识别方法:概念类分类列表、名词性短语)

(1)概念分类列表:人、事物、地点、组织、概念、事件、规则、抽象名词、交易项目、角色、设备、组织结构(对用例进行识别:实体、过程中的信息、角色的输入输出、操作设备等)

(2)名词分析法:识别问题域和用例描述中的名词和名词性短语作为候选的概念类和属性,从候选项中,摒弃多余的名词,确定最终的对象(注意是作为类还是属性,类可以是一种标识、状态和行为)

2、加属性

按照领域专家的说法就是 根据用例,给每个名词添加场景所涉及到的属性。

按照软件开发的说法就是 添加类的重要属性(类的语义完整性、类的作用、问题域相关特性等)

(1)语法:可见性 属性名:类型 多重性=默认值{特性表}

/  [可见性] 属性名 [:类型] [=初始值]

(2)属性类型是简单的数据类型为佳,如果是复杂概念,考虑是否单独作为一个概念类

(3)任何属性都不表示外键,即不应该用属性来联系概念类,区别于数据库设计中的外键

3、连关系

按照领域专家的说法就是找出领域对象之间的关系;

按照软件开发的说法就是建立类之间的关联(关联、继承、依赖)。

(1)关联:类之间的某种语义关系包括聚合,组合

(2)继承:一般到特殊

(3)依赖:表明一个元素(源元素)的定义或实现依赖另一个元素(被依赖元素)的定义或实现

领域驱动设计

领域驱动设计(Domain-Driven Design,DDD)是由Eric Evans最先提出,目的是对软件所涉及到的领域进行建模,以应对系统规模过大时引起的软件复杂性的问题。整个过程大概是这样的,设计团队、开发团队和领域专家一起通过“通用语言(Ubiquitous Language)”去理解和消化领域知识,从领域知识中提取和划分为一个一个的子领域(核心子域,通用子域,支撑子域),并在子领域上建立模型,再重复以上步骤,这样周而复始,构建出一套符合当前领域的模型。

1、 CRUD系统

在传统模型中,对象是数据的载体,只有简单的getter/setter方法,没有行为。以数据为中心,以数据库范式模型(即实体关系(ER)模型,用实体加关系描述的数据模型描述企业业务架构)设计作驱动,分层架构在这种开发模式下,可以理解 为是对数据移动、处理和实现的过程。这是一种贫血模型,这种模型开发出来的系统称为“ CRUD系统”。

简单的业务系统采用这种贫血模型和过程化设计是没有问题的,但在业务逻辑复杂的系统中,业务逻辑、状态会散落到在大量方法中,开发时间指数增长,维护成本很高,原本的代码意图会渐渐不明确,我们将这种情况称为由贫血症引起的失忆症。

CRUD系统,数据量一旦上来就会面临性能的问题,通常的解决方案就是对数据库进行读写分离。让主数据库处理事务性的增、删、改操作,让从数据库处理查询操作,然后主从数据库之间进行同步。但是这只是从DB角度处理了读写分离,从业务或者系统层面上来说,读和写的逻辑仍然是存放在一起的,他们都是操作同一个实体对象,并没有从底层基础设施上做根本改变。

2、CQRS系统

简单的说,CQRS(Command Query Responsibility Segration)就是一个系统,从架构上把 CRUD 系统拆分为两部分:命令(Command)处理和查询(Query)处理。其中命令处理包括增、删、改。命令与查询两边可以用不同的架构实现,以实现CQ两端(即Command Side,简称C端;Query Side,简称Q端)的分别优化。两边所涉及到的实体对象也可以不同,从而继续演变成下面这样。

(1)CQRS两种实现方式

A、CQ两端数据库共享,只是在上层代码上分离。这样做的好处是可以让我们的代码读写分离,更容易维护,而且不存在CQ两端的数据一致性问题,因为是共享一个数据库的。

B、CQ两端不仅代码分离,数据库也分离,然后Q端数据由C端同步过来。同步方式有两种:同步或异步,如果需要CQ两端的强一致性,则需要用同步;如果能接受CQ两端数据的最终一致性,则可以使用异步。C端可以采用Event Sourcing(简称ES)模式,所有C端的最新数据全部用Domain Event表达即可;而要查询显示用的数据,则从Q端的ReadDB(关系型数据库)查询即可。

(2)DDD的应用

CQRS是一种思想很简单清晰的设计模式,虽然在思想上简单,但是实现上相对来说复杂些,也涉及到DDD的一些概念了,他通过在业务上分离操作和查询来使得系统具有更好的可扩展性及性能,使得能够对系统的不同部分进行扩展和优化。在CQRS中,所有的涉及到对数据库(DB)的操作都是通过发送Command,然后特定的Command触发对应事件来完成操作,也可以做成异步的,主要看业务上的需求了。

当我们在分析某一领域时,一直在尝试如何将信息转化为领域模型,但并非所有的点我们都能用Model来涵盖。对象应当有属性、状态和行为,但有时领域中有一些行为是无法映射到具体的对象中的,我们也不能强行将其放入在某一个模型对象中,而将其单独作为一个方法又没有地方,此时就需要服务,这时候“微服务”诞生了。

微服务架构只是具体的实现方式,但是他并没有给出如何对复杂系统进行分解的具体方法论,而DDD强调领域模型和微服务设计的一体性正好就是解决方案, 用DDD(领域驱动设计) 的思想去指导微服务的实践,先有领域模型然后才有微服务,而不是脱离领域模型来谈微服务设计

中台的本质是领域模型,微服务是领域模型的系统落地,DDD是一种软件设计思想,它可以同时指导中台领域建模和微服务架构设计,这就是DDD、 微服务中台 的铁三角关系。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章