领域驱动模型设计(二)

目录

领域事件

领域、子域、核心域、通用域和支撑域

限界上下文

划分限界上下文

数据流转

上下文映射图

上下文集成

上一篇粗略地介绍了为什么需要使用领域驱动模型设计?下面我们将一一讲解下领域驱动设计中的一些比较难懂,但是却十分基础的概念。这些概念包括领域事件、领域、子域、核心域、通用域和支撑域,限界上下文,实体和值对象,聚合和聚合根。

领域事件

导致进一步的业务操作的事件,在 DDD 中这种事件被称为领域事件。

如果一次业务操作导致多个聚合状态的变更,应采用领域事件的最终一致性。

DDD“一次事务只更新一个聚合”的原则。

领域事件处理包括:事件构建和发布、事件数据持久化、事件总线、消息中间件、事件接收和处理等。

  • 事件构建和发布

事件基本属性事件唯一标识发生时间事件类型事件源,其中事件唯一标识应该是全局唯一的,以便事件能够无歧义地在多个限界上下文中传递。

业务属性:

记录事件发生那一刻的业务数据,这些数据会随事件传输到订阅方,以开展下一步的业务操作。

事件发布之前需要先构建事件实体并持久化

②事件数据持久化

  1. 持久化到本地业务数据库的事件表中,利用本地事务保证业务和事件数据的一致性。
  2. 持久化到共享的事件数据库中。这里需要注意的是:业务数据库和事件数据库不在一个数据库中,它们的数据持久化操作会跨数据库,因此需要分布式事务机制来保证业务和事件数据的强一致性,结果就是会对系统性能造成一定的影响。

事件总线 (EventBus)

事件总线是实现微服务内聚合之间领域事件的重要组件,它提供事件分发和接收等服务。事件总线是进程内模型,它会在微服务内聚合之间遍历订阅者列表,采取同步或异步的模式传递数据。

④消息中间件

跨微服务的领域事件大多会用到消息中间件,实现跨微服务的事件发布和订阅。消息中间件的产品非常成熟,市场上可选的技术也非常多,比如 Kafka,RabbitMQ 等。

事件接收和处理

微服务订阅方在应用层采用监听机制,接收消息队列中的事件数据,完成事件数据的持久化后,就可以开始进一步的业务处理。领域事件处理可在领域服务中实现。

领域事件运行机制相关案例

领域、子域、核心域、通用域和支撑域

现实世界中,领域包含了问题域解系统。一般认为软件是对现实世界的部分模拟。在DDD中,解系统可以映射为一个个限界上下文,限界上下文就是软件对于问题域的一个特定的、有限的解决方案。比如从事外卖业务,那么我们就需要解决商家和客户之间的问题,因此我们有了美团和饿了么。打车行业从传统出租车到互联网线上滴滴打车,为了解决私家车运力调度和用户打不到车的问题,就有了后面的滴滴打车。还有共享单车业务,解决我们最后一公里的问题,有了小黄车、小蓝车、小绿车。

在复杂和大规模软件开发过程中,我们可以通过分治的方法来解决。所以子域就是为了拆分各个复杂的领域,是问题逐步精细化,更加高类聚、低耦合,职责单一。比如我们要解决外卖问题,就自然产生了商家和客户两个子域。在客户子域下又可以划分为商品、下单、支付、派单等子子域,这时每个子子域可以对应一个微服务。

核心域是一个公司业务的核心,是公司建设的主体和战略发展的支撑点。例如不同的电商平台业务重心不同,核心域就有所不同。像拼过多的核心域就是拼购主打低价,跨境电商主打海外市场,京东主打物流和电子等。

通用域是一些基础功能,不包含业务概念,比如鉴权、日志、监控等。

支撑域就是有业务特点,作为业务的基础支撑,像一些业务状态码、数据字典等。

限界上下文

一个由显示边界限定的特定职责。领域模型便存在于这个边界之内。在边界内,每一个模型概念,包括它的属性和操作,都具有特殊的含义。一个给定的业务领域会包含多个限界上下文,想与一个限界上下文沟通,则需要通过显示边界进行通信。系统通过确定的限界上下文来进行解耦,而每一个上下文内部紧密组织,职责明确,具有较高的内聚性。一个很形象的隐喻:细胞质所以能够存在,是因为细胞膜限定了什么在细胞内,什么在细胞外,并且确定了什么物质可以通过细胞膜。

限界上下文是让业务在一定的范围内没有二义性。比如商品在电商领域中不同阶段的表现不同,在销售的时候是商品,在配送过程中是包裹。业务领域的不同,职责和含义就有所不同。所以界限上下文需要从业务出发,按领域划分。

划分限界上下文

我们的实践是,考虑产品所讲的通用语言,从中提取一些术语称之为概念对象,寻找对象之间的联系;或者从需求里提取一些动词,观察动词和对象之间的关系;我们将紧耦合的各自圈在一起,观察他们内在的联系,从而形成对应的界限上下文。形成之后,我们可以尝试用语言来描述下界限上下文的职责,看它是否清晰、准确、简洁和完整。简言之,限界上下文应该从需求出发,按领域划分

像外卖可以划分用户上下文、商家上下文、配送上下文。用户关注与外卖的价格、优惠、配送时长,商家关注商品对客户吸引力、利润,配送关注的是时长、配送费用、距离等。

数据流转

先领域的开放服务通过信息传输对象(DTO)来完成与外界的数据交互;在领域内部,我们通过领域对象(DO)作为领域内部的数据和行为载体;在资源库内部,我们沿袭了原有的数据库持久化对象(PO)进行数据库资源的交互。同时,DTO与DO的转换发生在领域服务内,DO与PO的转换发生在资源库内

与以往的业务服务相比,当前的编码规范可能多造成了一次数据转换,但每种数据对象职责明确,数据流转更加清晰

上下文映射图

康威(梅尔·康威)定律

任何组织在设计一套系统(广义概念上的系统)时,所交付的设计方案在结构上都与该组织的沟通结构保持一致。

团队结构(无论是内部组织还是团队间组织)就是组织结构,限界上下文就是系统的业务结构。

限界上下文之间的映射关系

  • 合作关系(Partnership):两个上下文紧密合作的关系,一荣俱荣,一损俱损。
  • 共享内核(Shared Kernel):两个上下文依赖部分共享的模型。
  • 客户方-供应方开发(Customer-Supplier Development):上下文之间有组织的上下游依赖。
  • 遵奉者(Conformist):下游上下文只能盲目依赖上游上下文。
  • 防腐层(Anticorruption Layer):一个上下文通过一些适配和转换与另一个上下文交互。
  • 开放主机服务(Open Host Service):定义一种协议来让其他上下文来对本上下文进行访问。
  • 发布语言(Published Language):通常与OHS一起使用,用于定义开放主机的协议。
  • 大泥球(Big Ball of Mud):混杂在一起的上下文关系,边界不清晰。
  • 另谋他路(SeparateWay):两个完全没有任何联系的上下文。

通过上下文映射关系,我们明确的限制了限界上下文的耦合性,即在抽奖平台中,无论是上下文内部交互(合作关系)还是与外部上下文交互(防腐层),耦合度都限定在数据耦合(Data Coupling)的层级。

上下文集成

通常集成上下文的手段有多种,常见的手段包括开放领域服务接口、开放HTTP服务以及消息发布-订阅机制

在抽奖系统中,我们使用的是开放服务接口进行交互的。最明显的体现是计数上下文,它作为一个通用上下文,对抽奖、风控、活动准入等上下文都提供了访问接口。 同时,如果在一个上下文对另一个上下文进行集成时,若需要一定的隔离和适配,可以引入防腐层的概念。这一部分的示例可以参考前文的防腐层代码示例。

下一篇:领域驱动模型设计(三)_张家老院子的博客-CSDN博客

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知始行末

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值