DDD领域建模实战——四色建模法(架构师必读)(ddd 四色原型)

新闻资讯2024-06-10 23:24小乐

DDD领域建模实战——四色建模法(架构师必读)(ddd 四色原型)

说说我个人的理解:四色造型是用来做什么的?在“系统分析”阶段,四色原型法并不要求建模前一定有需求。您在熟悉和了解业务的过程中可以直接使用四色原型分析。并表达业务,在任何理解业务的过程中都可以用它来抽象和组织业务概念。四色原型是一种思维工具,可以让系统分析师戴上有色眼镜看世界。通过将分析对象分为四大类,可以快速发现隐藏的概念和独立的职责,将模型对象变成概念上具有凝聚力、单一职责的对象,是系统分析过程中最有意义的思维工具。今天给大家分享一篇关于DDD领域建模的实用文章。它是根据我个人近三年来的DDD实践经验,基于企业级电商项目的DDD领域设计的。希望能给大家一些DDD方面的启发。我将从DDD领域分析、DDD设计呈现、领域建模实际案例开始讲解。稍后还有彩蛋给大家哦~话不多说,开始DDD之旅吧~

0x1

DDD领域分析在讲DDD之前,我们需要先了解一些基本概念。大家都知道DDD指的是领域驱动设计,那么我们如何理解DDD呢? DDD就是事件风暴(分类划分),然后知道组织划分(中台)、系统划分(微服务)、代码划分/设计的思维方法。这种理解可能比较抽象,但实际上其本质是通过将复杂的问题简单化、分解、克服来降低复杂性。 DDD的出现,符合当今流行的微服务架构。微服务架构有一个特别重要的命题——:如何合理划分微服务,而DDD的策略设计可以作为微服务划分的基础。当我们谈论DDD时,它实际上包括战略设计和战术设计。那么它们之间有什么区别呢?

战略设计:业务层面的领域建模,强调业务领域模型的识别和边界划分。简单来说就是业务设计,与代码呈现无关;战术设计:工程层面的架构设计和模型设计,具体应用于微服务即完成微服务设计。两者哪个更重要?我认为战略设计比战术设计更重要。在实际生产中,业务会越来越复杂,代码也会越来越大。如果业务不划分,表设计不划分和设计,最后系统就会变成一个巨大的单体应用,叠加需求修改代码。一旦发生,一根头发就会牵动全身。如果通过战略设计对业务进行合理划分,各个业务的业务边界就会特别清晰。即使我们的代码没有使用DDD思想来完成构建,即使我们仍然使用传统的MVC架构,也不会影响业务的正常运行。战略设计是产品需求和开发代码之间的桥梁。领域驱动的战略设计应该如何分析?我们不需要单独探索,我们可以总结前人的一些经验:

通用语言:它的作用是定义上下文含义,以便有界上下文定义域边界。事件风暴:由许多人参与,包括项目团队和领域专家,头脑风暴用于分析用户故事并找到并建立领域对象的四色构造。模型:按照时间发展的顺序,标识“溯源文件”作用的“时间尺度”概念直达核心业务数据;它强调可追溯性和执行效率之间的界限。纸笔建模:回到一百年前,在我们一个没有电脑的时代,我们会用什么方法来做商业设计?我们可以用纸笔画表写例子,管理核心领域的“刚好够用”的数据,增强数据完整性,避免过度设计DCI建模:也许我们对DCI的了解较少,但事实上, DCI架构和MVC架构是同一个人。 DCI建模通过角色扮演模型让领域模型变得简单易懂,通过小类和大对象避免出现上帝般的问题;同时还可以解决贫血模型和拥塞模型之间的争议,使模块更具内聚性和低耦合性;当然,DCI建模也可以与四色建模结合使用。那么,领域驱动的战术设计应该如何实施呢?在我看来,只考虑两个大方向:

模型设计:例如是否使用拥塞模型或贫血模型。架构设计:比如DDD/CQRS、干净架构、六边形架构、清晰架构、DCI架构……至此,我们对DDD的一些基本概念有了清晰的认识,那么为什么DDD对我们如此重要呢?我相信DDD可以指导我们的业务设计和代码实现,让维护变得更加简单。 DDD 指导设计:

从业务领域角度划分领域边界,构建高效沟通的通用语言,降低新团队成员熟悉业务的成本。在持续沟通的过程中,通过提炼领域概念和业务抽象来建立领域模型,以保持业务和代码的逻辑一致性。通过领域模型的分类和行为分析,保证业务实现的准确性。领域建模比数据库建模更轻量、更全面,而数据库建模不能完全反映系统的所有特性和需求。 DDD 指导实施:

在不过多依赖系统设计者的经验和背景的情况下,指导表设计和代码实现指导微服务的设计和拆分。 —— 划定了清晰的微服务边界,并允许轻松维护可持续发展的微服务架构:

从讨论、设计到评审和实现,都是使用领域模型进行沟通,领域模型可以作为系统业务的核心载体,在微服务的维度上划分有界上下文。服务拆分只需要去掉对应的有界上下文即可减少业务需求。迭代带来的维护成本(比如模型变更)这就是DDD对我们的重要性。我们不能只用发展的眼光来看待业务问题,否则就会陷入发展思维的陷阱,无助于我们业务的成长。接下来我们回顾一下DDD ——的核心要素有哪些

领域是指在特定范围或边界内要解决的业务问题域。其核心思想是将业务问题域细分为子域/核心域/通用域/支持域,以降低业务理解和系统实现的复杂度。聚合(Aggregate) 聚合包括聚合根、实体和值对象。 DDD 中的聚合并不等同于UML 中的聚合。我们使用拥塞模型来设计领域模型的属性和行为,并识别聚合和聚合根。值得注意的是,微服务至少应该不小于聚合,以避免引入分布式事务的复杂性。有界上下文(BC)业务的通用语言有其业务边界。我们不可能用一个简单的术语来毫无歧义地描述一个复杂的业务领域。 BC用于细分领域,从而定义共同的语言边界。 BC包含一个或多个聚合,根据业务领域概念划分为不同的BC。对应的Java代码级别是顶层包目录结构。 BC内部高内聚,一个业务行为应该尽可能使用BC内部的线程级交互,以保证ACID; BC之间耦合度低,可以作为微服务设计和拆分的基础。当然,微服务拆分的粒度也需要结合企业运维能力。 BC之间最好使用领域事件进行交互,或者引入一个“翻译器”(或防腐层)进行通信,以保持BC之间的松耦合。 DDD的核心要素就只有这三个。如果我们了解了这三个要素,我们就可以开始做很多事情。当然,我们还需要了解领域建模的一些难点,比如:

领域发现:难点在于领域模型的概念提炼、模型分析和分类;领域划分:难点在于如何清晰划分业务边界和应用边界,如何控制业务设计的粒度,是自下而上归纳划分还是自上而下归纳划分。演绎除法;领域建模:难点在于如何识别聚合、聚合根、实体、值对象,如何建立领域模型之间的关系和核心交互等。

0x2

DDD设计演示——四色造型

当我们收到需求时,我们会在脑海中过一遍实现代码。这对于简单的CRUD来说并不困难,但是当涉及到更复杂的业务时,一个场景我们就需要很长时间才能沟通清楚。我们应该做什么?呢绒?其实很简单。我们需要一个载体来沉淀思维过程。当产品经理来找我们增加需求评估的范围时,当新员工入职并向他解释业务时,这个载体都可以直观地呈现出来。这就是DDD设计呈现的魅力。这里我使用我个人比较容易使用的四色建模方法作为DDD的设计呈现。四色建模方法是一种领域模型的分析方法。重点是领域模型的分类。它是一种呈现方法。四色原型诞生于20世纪90年代。它首先由Peter Coad 和Mark Mayfield [Coad92] 提出,然后由David North [Coad95-97] 扩展。它是一种广泛使用的系统分析方法。使用四色建模方法设计的四色图表达了类图,该类图是包括序列图的完全动态图。它是三维的、多维的,与完全静态的数据库ER图不同。那么四色原型机具体有哪四种颜色呢?我们看一下:时刻间隔原型(MI)表示在某一时刻或某段时间内发生的事情,例如销售订单、客户账单、付款记录等,用浅红色表示。 PPT原型(Part-Place-Thing Archetype,People/Thing/Thing Archetype,简称PPT)代表扮演不同角色的人或物,如产品、账户、商店等,用浅绿色表示。角色原型(简称ROLE)抽象出一种参与方式,由人或组织、场所或物品承担,如客户、商家、仓储团队、金融组织等,用浅黄色表示。描述Archetype(简称DESC)是一种数据类型的资源,目录类型对象,或者可以被其他原型重复使用,例如产品类别、支付方式、方法值对象等,用浅蓝色表示。接下来我们使用四色建模方法来分析领域模型,分为四大步骤:

建立时间尺度原型:寻找需要追踪的事件,并根据追踪的事件找到足迹。建立PPT原型:丰富模型,围绕时间尺度原型寻找人/事/物,使其能够更好地描述业务理念。建立角色原型:进一步学习。抽象出可以参与不同流程的角色,建立描述原型:用描述对象补充一些信息。这里需要注意的是,整个过程中会穿插一些原型之间的关系/核心交互的注释。我们来看一个电商DDD的四色图示例:

0x3

领域建模的实际案例如下图所示。这是金融领域模型和支付中心模型的一部分。只描述了业务系统如何运行,不涉及表的具体字段设计。完整模型图涉及敏感信息,不详细展示:

领域建模就是这样一种建模。这里我提一下一些设计细节:

粉色指的是时间尺度原型,是核心业务产生的数据。基本上,对应的表设计模型属性不需要体现表的审计字段,比如通用ID、创建者、修改时间、软删除标识等,模型行为也只需要设计核心行为即可。不需要写出常规的CRUD方法。设计必须知道如何在BC内选择模型。除了依赖关系、聚合等之外,还可以使用箭头来连接跨BC 的模型之间的核心交互。它们之间的模型通过虚线箭头连接。这里我结合DCI建模方法(D代表数据,C代表上下文和场景,I代表模型之间的交互)。针对业务的独特属性,我采用加粗的方式展示。您不再需要费心与其他人一起分析用于构建这些模型的维度。对于尚未上线的属性变更(新增/修改),使用红色标记,因为领域模型图是有界上下文的划分,指导我们的业务发展。这是一个非常主观的边界划分。为了后续代码的灵活调整,不需要在Controller的URL设计中添加有界上下文域模型图。就像代码一样,它需要我们长期维护。并不意味着设计完成后就不会完成。去吧,照顾好它。这个非常重要。微服务负责人必须有这个意识。

猜你喜欢