前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

一、服务契约设计

在软件领域,使用最频繁的词语之一就是“服务”。领域驱动设计也有领域服务和应用服务之分,菱形对称架构则将开放主机服务分为远程服务和本地服务,其中本地服务即 Eric Evans 提出的应用服务。全局分析阶段输出的业务需求也被我称为业务服务。

业务服务满足了角色的服务请求,在解空间体现为服务与客户的协作关系,形成的协作接口可称为契约(contract一个业务服务对应于架构映射阶段需要定义的服务契约[1],体现为菱形对称架构北向网关的开放主机服务。服务契约面向服务模型,它向客户端传递的消息数据称为消息契约。消息契约是组成服务契约的一部分

限界上下文:

  • 上方:代表北向服务,为当前限界上下文对外公开的服务接口
  • 下方:代表南向服务,为当前限界上下文调用上游限界上下文或伴生系统的服务接口
  • 左方:当前限界上下文订阅的事件
  • 右方:当前限界上下文发布的事件

image-20240821213410529

菱形对称架构

菱形对称架构的核心思想:

  • 内外分离:内部的领域层与外部的网关层分离,保证业务和技术的正交性
  • 南北对称:南向网关采用抽象思想,隔离外部资源变化对内部领域层带来的影响;北向网关采用封装思想,通过定义远程服务和本地服务隔离内部领域逻辑对外部调用者的影响

image-20240821213502666

1、消息契约

消息契约对应上下文映射的发布语言模式,根据客户端发起对服务操作的类型,分为命令、查询和事件

不同的操作类型决定了客户端与服务端不同的协作模式

常见的客户端与服务端不同的协作模式

协作模式 操作类型
请求/响应模式  
即发即忘模式 发送方发送一个请求消息后,不等待或期望接收方发送任何响应消息
发布/订阅模式 消息发送与订阅

客户端发起对服务操作的类型

名词 解释 协作模式
命令 是一个动作,要求其他服务完成某些操作,会改变系统的状态 命令操作如果需要返回操作结果,也需选择请求/响应模式,否则可以选择即发即忘模式
查询 是一个请求,查看是否发生了什么事。重要的是,查询操作没有副作用,也不会改变系统的状态。 查询操作采用请求/响应模式
事件 既是事实又是触发器,用通知的方式向外部表明发生了某些事。 事件选择发布/订阅模式

1)消息契约模型

操作类型与协作模式决定了消息契约模型

1、遵循请求/响应协作模式的消息契约分为请求消息与响应消息。请求消息按照操作类型的不同分为查询请求(query request)和命令请求(command request)。 若操作为命令,返回的响应消息为命令结果(command result); 若操作为查询,返回的响应消息又分为两种:面向前端 UI 的视图模型( view model )与面向下游限界上下文的数据契约(data contract)。

2、遵循即发即忘协作模式的消息契约只有命令请求消息,

3、遵循发布/订阅协作模式的消息契约就是事件本身。

整个消息契约模型如下图:

image-20240821183224160

2、设计服务契约

1)业务服务的细化

对发起服务请求的角色而言,目标系统是一个黑箱。但到了架构映射阶段,目标系统的问题空间已经被映射为由多个限界上下文组成的解空间,一个业务服务有可能需要多个限界上下文共同协作。因此,要设计服务契约,就应该围绕着业务服务开展。

设计服务契约的前提是已经识别出目标系统的限界上下文。当我们开始针对业务服务进行梳理时,可以抹去领域逻辑的细节,重点关注

为了弄清楚参与业务服务的协作方式,需要为业务服务编写业务服务规约。例如,文学平台的发布作品业务服务规约如下

服务编号:L0006

服务名:发布作品

服务描述:作为作者,我想要发布我的作品,以便更多读者阅读我的作品

触发事件:作者点击“发布文章”按钮 基本流程:

​ 1、检查作品是否符合发布标准

​ 2、对作品内容进行违规检查

​ 3、发布作品

​ 4、发送消息通知作品的订阅者 替代流程: ​ 1、如果作品不符合发布标准,提示“作品不符合发布标准

​ 2、如果作品内容未通过违规检查,提示“作品内容包含敏感内容,禁止发布”

​ 3、如果作品发布失败,提示失败原因”

验收标准: 1、作品标题字数不得超过50个字符(1个汉字为2个字符)

​ 2、作品标题只能使用汉字、英文字符和数字

​ 3、发布的作品必须包含标题、作品类型和作品内容,且内容在规定字数范围内

​ 4、作品发布成功后,状态为“已发布”

​ 5、作品的订阅者收到作品发布的通知

​ 6、作品的订阅者可以阅读已发布的作品”

2)服务序列图

理出业务服务规约有利于我们根据业务的执行步骤绘制服务序列图,服务序列图的本质是 UML 的序列图。引入服务序列图的目的就是弄清楚限界上下文之间、限界上下文与伴生系统、外部调用者与限界上下文之间的执行序列,从而帮助我们确定服务契约

针对每一个业务服务,通过业务服务规约绘制服务序列图,以确定限界上下文之间的协作关系,并驱动出每个限界上下文的服务契约。绘制服务序列图时,根据业务服务规约“成功场景”部分的流程,确定每个流程步骤需要的领域知识和领域职责应该由哪一个限界上下文负责。服务序列图如下所示:

image-20240821212111313

image-20240821211553552

3)服务契约的表示

通过服务序列图,既可以明确限界上下文之间的关系,又可以驱动出每个限界上下文包括伴生系统的服务契约(API),同时还能够确定协作模式,包括客户方-供应方模式和发布者-订阅者模式。其中,查询和命令方式属于客户方-供应方模式,事件方式属于发布者-订阅者模式。服务契约可以通过下表格式表示:

表现服务契约的格式并不重要,只要能清晰描述服务契约基本属性,未后续领域建模提供设计参考,怎么样的格式都可以

image-20240821211805893

ContactAuthor