内容总结自《微服务架构设计模式》
微服务架构中的业务逻辑设计
- 一、业务逻辑组织模式
- 使用事务脚本模式设计业务逻辑
- 使用领域模型模式设计业务逻辑
- 二、使用聚合模式设计领域驱动
- 聚合拥有明确的边界
- 聚合的规则
- 聚合的粒度
- 三、领域事件
- 什么是领域事件
- 什么是事件增强
- 哪些是领域事件
- 生成和发布领域事件
- 四、总结
一、业务逻辑组织模式
使用事务脚本模式设计业务逻辑
虽然我一直积极地倡导使用面向对象的方式,但在某些情况下使用面向对象的设计方法会有一种“杀鸡用牛刀”的感觉,例如在开发简单的业务逻辑时。在这种情况下,更好的方法是编写面向过程的代码,并使用Martin Fowler在《Patterns of Enterprise ApplicationArchitecture》 (Addison-Wesley Professional,2002年)一书中提到的事务脚本模式。你可以编写一个称为事务脚本的方法来处理来自表示层的每个请求,而不是进行任何面向对象的设计。
这种方法的一个重要特征是实现行为的类与存储状态的类是分开的。
使用领域模型模式设计业务逻辑
将业务逻辑组织为由具有状态和行为的类构成的对象模型。
在面向对象的设计中,业务逻辑由对象模型和相对较小的一些类的网络组成。这些类通常直接对应于问题域中的概念。在这样的设计中,有些类只有状态或行为,但很多类同时包含状态和行为,这样的类都是精心设计的。
二、使用聚合模式设计领域驱动
聚合拥有明确的边界
聚合是一个边界内的领域对象的集群,可以将其视为一个单元。它由根实体和可能的一个或多个其他实体和值对象组成。许多业务对象都被建模为聚合。
将领域模型组织为聚合的集合,每个聚合都是可以作为一个单元进行处理的一组对象构成的图。
聚合的规则
领域驱动设计要求聚合遵守一组规则。这些规则确保聚合是一个可以强制执行各种不变量约束的自包含单元。
规则一:只引用聚合根
规则二:聚合间的引用必须使用主键
规则三:在一个事务中,只能创建或更新一个聚合
聚合的粒度
在开发领域模型时,你必须做出的关键决策是决定每个聚合的大小。一方面,聚合理想上应该很小。由于每个聚合的更新都是序列化的,因此更细粒度的聚合将提高应用程序能同时处理的请求数量,从而提高可扩展性。它还将改善用户体验,因为它降低了两个用户尝试同时更新一个聚合而引发冲突的可能性。但是另一方面,因为聚合是事务的范围,所以你可能需要定义更大的聚合以使特定的聚合更新操作满足事务的原子性。
三、领域事件
什么是领域事件
在领域驱动设计的上下文中,领域事件是聚合发生的事情。它由领域模型中的一个类表示。事件通常代表状态的变化。即,聚合在被创建时,或发生其他重大更改时发布领域事件。
在命名领域事件时,我们往往选择动词的过去分词。这样的命名能够明确表达事件的一些属性。领域事件的每个属性都是原始值或值对象。例如,Ordercreated事件类具有orderId属性。
什么是事件增强
即事件包含的数据是事件的简化内容,如id。还是接受方需要的事件内容信息
虽然事件增强简化了接收方,但缺点是它可能会使领域事件的稳定性降低。每当接收方的需求发生变化时,事件类都可能需要更改。这可能会降低可维护性,因为这种更改会影响应用程序的多个部分曰。尝试满足每个接收方也可能是徒劳的。幸运的是,在很多情况下,在事件中应该包含哪些属性是相当明显的。
哪些是领域事件
一种是软件的需求会描述需要发送通知的场景。需求可能包括诸如“当X发生时做Y”之类的语言。
另一种越来越流行的方法是使用事件风暴。事件风暴是一种以事件为中心的研讨会,用于理解复杂的领域。它的具体方法是:把领域专家聚集在一个屋子里,准备大量便笺和一个非常大的白板。事件风暴的结果是一个以事件为中心的领域模型,它由聚合和事件组成。
生成和发布领域事件
从概念上讲,领域事件由聚合负责发布。聚合知道其状态何时发生变化,从而知道要发布的事件。聚合可以直接调用消息传递API。这种方法的弊端在于,由于聚合不能使用依赖注入,所以消息传递API需要作为方法参数传递。这将把基础设施和业务逻辑交织在一起是非常不可取的。
更好的方法是在聚合和调用它的服务(或类)之间分配职责。服务可以使用依赖注入来获取对消息传递API的引用,从而轻松发布事件。只要状态发生变化,聚合就会生成事件并将它们返回给服务。
四、总结
- 事务脚本模式通常是实现简单业务逻辑的好方法。但是在实现复杂的业务逻辑时,应该考虑使用面向对象的领域模型模式。
- 设计服务的业务逻辑的好方法是使用DDD聚合。DDD聚合很有用,因为它们把领域模型模块化,消除了服务之间对象的直接引用,并确保每个ACID事务都在服务内。
- 创建或更新聚合时应发布领域事件。领域事件具有广泛的用途。领域事件的订阅者还可以通知用户和其他应用程序,并将WebSocket消息发布到用户的浏览器。