“极客时间”《DDD 实战》课程笔记 (五)微服务设计的边界和视图概念
这是一系列学习笔记,对象是 极客时间 上面的收费课程 《 DDD实战 》。这是第5篇,简单记录一下微服务设计相关的一些领域概念。
微服务边界
在谈论微服务设计时,微服务如何拆分是绕不过的话题。
演进式架构
微服务有一个重要特征是“演进式架构”,演进式架构就是以支持增量的、非破坏的变更作为第一原则,同时支持在应用程序结构层面的多维度变化。
微服务的重点就是看微服务设计是否能够支持架构长期、轻松的演进。随着业务的发展或需求的变更,在不断重新拆分或者组合成新的微服务的过程中,不会大幅增加软件开发和维护的成本,并且这个架构演进的过程是非常轻松、简单的。
微服务还是小单体?
有些团队在将单体应用拆分为微服务时,首先进行的不是建立领域模型,而是按照业务功能将原来的一个软件包拆分成多个所谓的“微服务”软件包,其中代码仍然是三层架构的模式,高度耦合,边界不清晰,这就是“小单体微服务”。
随着需求的提出和业务的发展,小单体会慢慢膨胀起来。当有一天有部分业务功能需要拆分出去,或者部分功能需要与其它微服务进行重组时,会发现原来这些看似清晰的微服务,不知不觉已经摇身一变成了臃肿油腻的大单体了。辛辛苦苦好多年,一夜回到解放前啊!
这种单体式微服务只定义了微服务之间的物理边界,本质上还是单体架构模式。微服务设计时不仅只有这个边界,还要定义好逻辑边界和代码边界。
逻辑边界
逻辑边界主要定义同一业务领域或应用内紧密关联的对象所组成的不同聚合间的组合。事件风暴会产生多个聚合和限界上下文,它们一起组成这个领域的领域模型。微服务内聚合之间的边界就是逻辑边界。
一般来说微服务会有一个以上的聚合,在开发过程中不同聚合的代码在不同的聚合代码目录中。
微服务的架构演进需要遵循的规则就是逻辑边界。架构演进时,在业务端以聚合为单位进行业务能力的重组,在微服务端以聚合的代码目录为单位进行微服务代码的重组。由于按照 DDD 方法设计的微服务逻辑边界清晰,在领域模型和微服务代码重构时就不需要花费太多的时间和精力了。
物理边界
物理边界主要从部署和运行的视角来定义微服务之间的边界。不同微服务部署位置和运行环境是相互物理隔离的,分别运行在不同的进程中。
代码边界
代码边界主要用于微服务内的不同职能代码之间的隔离。微服务开发过程中会根据代码模型建立相应的代码目录,实现不同功能代码的隔离。由于领域模型与代码模型的映射关系,代码边界直接体现出业务边界。代码边界可以控制代码重组的影响范围,避免业务和服务之间的相互影响。微服务如果需要进行功能重组,只需要以聚合代码为单位进行重组就可以了。
微服务视图
DDD架构供4层,前面说过(第三篇笔记)建议使用严格架构,即不能跨层调用。这里说一下相邻层间的数据对象。
- 数据持久化对象 PO(Persistent Object),与数据库结构一一映射,是数据持久化过程中的数据载体。
- 领域对象 DO(Domain Object),微服务运行时的实体,是核心业务的载体。
- 数据传输对象 DTO(Data Transfer Object),用于前端与应用层或者微服务之间的数据组装和传输,是应用之间数据传输的载体。
- 视图对象 VO(View Object),用于封装展示层指定页面或组件的数据。
他们之间的关系和转换看下图:

在软件开发过程中,需要严格遵守各层服务和数据的职责要求,各据其位,各司其职。这样才能保证核心领域模型的稳定,同时也可以灵活应对外部需求的快速变化。
