聚合架构设计规范:从三收拢点到多元聚合的工程范式
副标题:基于 WorkFlowPrj 项目实践的架构设计方法论
版本:v3.0(理论重构版) |更新日期:2026-07-23
关键词:聚合架构、三收拢点、统一入口、管线聚合、架构规范、聚合度理论
目录
- 聚合架构设计规范:从三收拢点到多元聚合的工程范式
- 目录
- 引言:聚合架构的起源与定位
- 第一部分:聚合架构的理论基础
- 一、聚合的本质
- 1.1 聚合的定义
- 1.2 聚合的演进动因
- 二、聚合的拓扑结构
- 2.1 点聚合(Point Aggregation)
- 2.2 线聚合(Pipeline Aggregation)
- 2.3 面聚合(Facade Aggregation)
- 2.4 三种拓扑的关系
- 三、聚合度理论
- 3.1 内聚度(Cohesion)
- 3.2 收敛度(Convergence)
- 3.3 边界清晰度(Boundary Clarity)
- 3.4 聚合度评估矩阵
- 四、聚合与解耦的辩证关系
- 4.1 隐式耦合 vs 显式耦合
- 4.2 聚合与解耦的平衡
- 五、聚合架构的核心价值
- 5.1 可审计(Auditable)
- 5.2 可维护(Maintainable)
- 5.3 可演化(Evolvable)
- 5.4 三者的关系
- 一、聚合的本质
- 第二部分:聚合架构的设计规范
- 一、聚合点识别原则
- 原则 1:外部依赖收敛
- 原则 2:数据流边界收敛
- 原则 3:能力出口收敛
- 原则 4:变更热点收敛
- 二、聚合边界划分规范
- 规范 1:单一职责
- 规范 2:边界内完整
- 规范 3:边界间无重叠
- 三、聚合间通信契约
- 契约形式
- 契约规范
- 四、聚合的测试策略
- 测试金字塔
- 五、聚合的演化与重构
- 聚合点演化的信号
- 聚合点重构的步骤
- 一、聚合点识别原则
- 第三部分:聚合架构的实现模式
- 模式一:三收拢点模式
- 1.1 模式概述
- 1.2 三个收拢点的职责
- 1.3 模式的核心设计决策
- 1.4 模式的设计收益
- 模式二:统一调用入口模式
- 2.1 模式概述
- 2.2 模式的核心设计决策
- 2.3 模式的设计约束
- 模式三:管线聚合模式
- 3.1 模式概述
- 3.2 模式的核心设计决策
- 3.3 脏标记与增量执行
- 模式对比与选择指南
- 模式一:三收拢点模式
- 第四部分:反模式与演进
- 一、聚合架构的常见反模式
- 1. 上帝聚合(过度聚合)
- 2. 分散聚合(聚合不足)
- 3. 隐式聚合(无明确边界)
- 4. 循环聚合(聚合间循环依赖)
- 二、聚合架构的未来演进
- 方向一:从手动聚合到自动聚合
- 方向二:从静态聚合到动态聚合
- 方向三:从单层聚合到多层聚合
- 核心思想
- 一、聚合架构的常见反模式
引言:聚合架构的起源与定位
在软件系统的演化过程中,一个不可回避的规律是:系统越复杂,信息流动的路径就越分散,系统的可理解性就越低。当一个模块的内部实现细节散落在多个文件中,当数据流入和流出的路径不明确,当操作散布在系统的各个角落——维护成本将呈指数级上升。
聚合架构正是为解决这一问题而生。它不是对"解耦"的否定,而是对"解耦"的补充——解耦解决的是"模块间如何减少依赖"的问题,聚合解决的是"模块内如何管理复杂度"的问题。两者相辅相成,共同构成一个可维护、可审计、可演化的软件架构。
本文档从 WorkFlowPrj 项目的工程实践中提炼而来,按照理论 → 规范 → 模式 → 反模式的认知路径组织,旨在为聚合架构的设计提供系统化的理论框架和实践指南。
第一部分:聚合架构的理论基础
本部分回答:聚合是什么?为什么需要聚合?如何衡量聚合的合理性?
一、聚合的本质
1.1 聚合的定义
在软件架构的语境中,聚合(Aggregation)是指:
将一组相关的操作、数据流或能力收敛到一个明确定义的边界内,对外暴露统一的契约接口,对内封装实现细节的架构模式。
聚合包含三个核心要素:
聚合 = 边界(Boundary) + 契约(Contract) + 实现(Implementation)| 要素 | 含义 | 设计关注点 |
|---|---|---|
| 边界 | 聚合的职责范围,什么属于内部、什么属于外部 | 边界是否清晰、是否完整、是否重叠 |
| 契约 | 聚合对外暴露的接口,包括输入、输出、异常 | 契约是否稳定、是否完备、是否可测试 |
| 实现 | 聚合内部的实现细节,对外部完全隐藏 | 实现是否可替换、是否可独立演化 |
1.2 聚合的演进动因
聚合架构的引入通常经历三个阶段:
| 阶段 | 特征 | 核心问题 |
|---|---|---|
| 分散期 | 操作散落各处,数据流路径不明确 | 难以审计、难以替换、难以理解 |
| 收敛期 | 识别关键收敛点,逐步收拢操作路径 | 收敛点是否合理、是否完整 |
| 规范期 | 将收敛经验提炼为架构规范 | 规范是否可复用、是否可传承 |
聚合架构的核心洞察是:在复杂系统中,信息流动的路径必须被显式管理。不是所有的分散都是"解耦",不是所有的聚合都是"耦合"。关键在于识别出哪些路径需要被收敛,哪些路径需要保持开放。
二、聚合的拓扑结构
聚合架构可以从拓扑学角度分为三种基本结构:
2.1 点聚合(Point Aggregation)
定义:将分散的同类操作收敛到一个单一入口点。
特征:
- 一个入口点对应一类操作
- 操作类型单一(如"所有数据输入")
- 内部可能包含多个实现类
示例:三收拢点模式中的EcsInputPort——所有数据输入都经过这一个点。
适用场景:外部依赖收敛、数据流边界收敛。
2.2 线聚合(Pipeline Aggregation)
定义:将一组有序的执行步骤编排为一条管线,对外暴露统一的触发入口。
特征:
- 多个步骤按顺序执行
- 步骤间通过数据对象传递状态
- 整体对外表现为一个操作
示例:管线聚合模式中的EcsRenderPipeline.ExecutePipeline()——多个 System 按阶段执行。
适用场景:流程编排、阶段式处理。
2.3 面聚合(Facade Aggregation)
定义:将一个模块的所有公开能力收敛到一个统一的入口面中。
特征:
- 覆盖模块的所有公开能力
- 入口层薄(只做转发)
- 内部实现保持模块化
示例:统一调用入口模式中的WorkflowMethodUsage——13 个功能区域的统一入口。
适用场景:模块能力出口收敛。
2.4 三种拓扑的关系
三种拓扑结构可以嵌套组合:
面聚合(模块入口) └── 线聚合(管线编排) └── 点聚合(System 内部收敛)这种嵌套关系构成了聚合架构的层次化结构,使得系统在不同粒度上都能保持可控。
三、聚合度理论
聚合度(Degree of Aggregation)是衡量聚合设计合理性的理论框架。它从三个维度评估一个聚合点的质量:
3.1 内聚度(Cohesion)
定义:聚合内部各元素之间的关联强度。
| 内聚等级 | 描述 | 示例 |
|---|---|---|
| 功能内聚(最高) | 内部元素共同完成一个功能 | EcsInputPort的所有方法都服务于"数据输入" |
| 通信内聚 | 内部元素操作同一数据 | WinFormsOutputPort的所有方法都操作控件状态 |
| 时间内聚 | 内部元素在同一时间执行 | 管线聚合中的 System 在同一管线中执行 |
| 逻辑内聚(最低) | 内部元素仅因逻辑分类而聚集 | 一个类同时包含输入和输出方法 |
设计目标:达到功能内聚或通信内聚。
3.2 收敛度(Convergence)
定义:外部依赖被聚合点收敛的比例。
收敛度 = 经过聚合点的操作数 / 该类操作的总数| 收敛等级 | 描述 | 风险 |
|---|---|---|
| 完全收敛(100%) | 所有操作都经过聚合点 | 理想状态 |
| 部分收敛(50%-99%) | 大部分操作经过聚合点 | 存在绕过风险 |
| 低收敛(<50%) | 少数操作经过聚合点 | 聚合点形同虚设 |
设计目标:达到完全收敛。任何绕过聚合点的操作都是架构违规。
3.3 边界清晰度(Boundary Clarity)
定义:聚合边界是否明确、无歧义、无重叠。
| 清晰等级 | 描述 | 示例 |
|---|---|---|
| 清晰 | 边界明确,无重叠 | EcsInputPort只负责输入,不操作控件 |
| 模糊 | 边界存在灰色地带 | 输入端口偶尔操作控件 |
| 重叠 | 多个聚合点职责重叠 | 两个类都负责控件创建 |
设计目标:达到清晰等级。
3.4 聚合度评估矩阵
| 维度 | 优秀(3分) | 合格(2分) | 不合格(1分) |
|---|---|---|---|
| 内聚度 | 功能内聚 | 通信内聚 | 逻辑内聚 |
| 收敛度 | 完全收敛(100%) | 部分收敛(≥80%) | 低收敛(<80%) |
| 边界清晰度 | 清晰 | 模糊但可控 | 重叠 |
评估方法:对每个聚合点按三个维度打分,总分 ≥ 7 为优秀,5-6 为合格,< 5 需要重构。
四、聚合与解耦的辩证关系
聚合常被误解为"耦合"的同义词。实际上,聚合与解耦是互补的:
解耦:减少模块间的直接依赖 聚合:将分散的相关操作收敛到统一入口4.1 隐式耦合 vs 显式耦合
正确的聚合不会增加耦合,而是将隐式的、分散的耦合转化为显式的、集中的耦合。
| 类型 | 描述 | 示例 |
|---|---|---|
| 隐式耦合(❌) | 10 个地方直接操作 WinForms 控件,每个地方都依赖控件的具体类型 | 分散的control.Text = ... |
| 显式耦合(✅) | 所有控件操作经过WinFormsOutputPort,外部只依赖Apply(CanonicalForm)契约 | 集中的port.Apply(form) |
隐式耦合是不可控的——你不知道有多少地方依赖控件的具体类型,也无法在不破坏现有代码的情况下替换控件实现。显式耦合是可控的——所有依赖都指向同一个契约,替换实现只需修改聚合点内部。
4.2 聚合与解耦的平衡
聚合和解耦不是非此即彼的选择,而是在不同维度上的设计决策:
高解耦 + 高聚合 = 理想状态(模块间松散,模块内紧凑) 高解耦 + 低聚合 = 碎片化(模块间独立,但模块内也分散) 低解耦 + 高聚合 = 单体(模块间紧密,但模块内有序) 低解耦 + 低聚合 = 混乱(最差状态)设计目标:追求高解耦 + 高聚合——模块间通过契约通信,模块内通过聚合收敛。
五、聚合架构的核心价值
聚合架构追求三个核心价值,三者相互促进:
5.1 可审计(Auditable)
所有关键操作都经过明确的入口/出口,形成可追踪的审计链。
- 数据从哪里来?→
EcsInputPort - 数据到哪里去?→
WinFormsOutputPort - 当前状态是什么?→
CsgEntryPoint.Collect()
5.2 可维护(Maintainable)
变更的影响范围被聚合边界限制,修改一个聚合的内部实现不影响外部。
- 替换 WinForms 实现 → 只需修改
WinFormsOutputPort - 修改布局算法 → 只需修改
LayoutSystem - 新增数据源 → 只需扩展
EcsInputPort
5.3 可演化(Evolvable)
聚合的内部实现可以被替换、升级、重构,只要保持对外契约不变。
- 从同步变为异步 → 契约不变,内部实现变化
- 从本地变为远程 → 契约不变,内部实现变化
- 从单体变为微服务 → 契约不变,内部实现变化
5.4 三者的关系
可审计的架构更容易定位问题从而降低维护成本,清晰的边界使得内部实现替换不影响外部契约从而支持演化。聚合架构的目标是在三者之间找到适合项目阶段的最优平衡点。
第二部分:聚合架构的设计规范
本部分回答:如何设计聚合?设计聚合需要遵循哪些规范?
一、聚合点识别原则
在架构设计中,识别哪些点需要聚合是第一步。以下是四条识别原则:
原则 1:外部依赖收敛
当多个内部组件依赖同一个外部资源(框架、库、服务)时,必须创建一个聚合点封装该依赖。
理论依据:外部依赖是系统中最易变的部分。将依赖收敛到一个点,可以隔离变更影响。
判断方法:搜索代码库中对外部资源的引用,如果同一资源的引用出现在 3 个以上的文件中,就需要创建聚合点。
示例:
- 所有 WinForms 控件操作 →
WinFormsOutputPort - 所有数据输入 →
EcsInputPort
原则 2:数据流边界收敛
当数据从一个子系统流向另一个子系统时,必须在边界处创建聚合点。
理论依据:子系统边界是数据流最复杂的区域。在边界处创建聚合点,可以确保数据流的完整性和可审计性。
判断方法:识别系统中的子系统边界,检查边界处的数据流是否有统一的入口/出口。
示例:
- ECS World → WinForms 控件:
CsgEntryPoint+WinFormsOutputPort - 外部配置 → ECS World:
EcsInputPort
原则 3:能力出口收敛
当一个模块对外提供多个能力时,必须创建一个统一的调用入口。
理论依据:多个出口意味着外部调用方需要了解模块的内部结构。统一入口可以降低外部使用成本。
判断方法:检查模块的公开类型数量,如果外部调用方需要引用 3 个以上的类型才能使用模块,就需要创建统一入口。
示例:
- WorkFlowMethod 的 13 个功能区域 →
WorkflowMethodUsage - 管线执行 →
EcsRenderPipeline.ExecutePipeline()
原则 4:变更热点收敛
当某个点频繁变更时,必须将其收敛到一个聚合点中,限制变更的影响范围。
理论依据:频繁变更是架构脆弱性的信号。将变更热点收敛,可以隔离变更影响,防止"蝴蝶效应"。
判断方法:使用版本控制系统分析文件变更频率,如果某个功能点的变更频率是平均值的 2 倍以上,就需要创建聚合点。
示例:
- 控件创建逻辑 →
EcsCapabilityApplier - 布局计算逻辑 →
LayoutSystem
注意:这里的"聚合点"是广义的——指代被收敛的职责单元。
EcsCapabilityApplier和LayoutSystem是管线聚合内部的 System,它们本身不是独立的聚合点,而是管线聚合模式中"阶段式编排"的一个环节。狭义的聚合点特指对外暴露统一入口的收拢点(如三收拢点、统一调用入口)。
二、聚合边界划分规范
规范 1:单一职责
一个聚合点只负责一个维度的收敛:
| 聚合点 | 职责维度 | 不负责 |
|---|---|---|
| EcsInputPort | 数据输入 | 控件操作、状态收集 |
| CsgEntryPoint | 状态收集 | 数据输入、控件操作 |
| WinFormsOutputPort | 控件差异更新 | 数据输入、状态收集、控件创建 |
| WorkflowMethodUsage | 能力出口 | 内部实现、状态管理 |
反模式对照→ 上帝聚合(过度聚合)
规范 2:边界内完整
聚合边界内的能力必须完整覆盖该维度的所有场景:
EcsInputPort必须覆盖所有数据输入场景(配置加载、事件回传、数据变更)WinFormsOutputPort必须覆盖所有控件差异更新场景(全量 Apply、快速路径 ApplyValueChange)WorkflowMethodUsage必须覆盖所有公开能力
注意:控件的创建由管线中的
EcsCapabilityApplier负责,WinFormsOutputPort只负责控件状态的差异更新。两者通过管线编排协作,职责不重叠。
反模式对照→ 分散聚合(聚合不足)
规范 3:边界间无重叠
聚合边界之间不允许有职责重叠:
- 如果
EcsInputPort直接操作控件,就和WinFormsOutputPort的职责重叠了 - 如果
LayoutSystem直接输出 CSG,就和CsgEntryPoint的职责重叠了
反模式对照→ 隐式聚合(无明确边界)
三、聚合间通信契约
聚合点之间的通信必须通过明确定义的契约:
契约形式
| 通信方式 | 适用场景 | 耦合度 | 示例 |
|---|---|---|---|
| 方法调用 | 同步、同进程 | 编译时耦合 | EcsInputPort.LoadConfig() |
| 事件/委托 | 异步、解耦 | 运行时耦合 | EcsInputPort.DataChanged |
| 数据对象 | 跨边界传输 | 数据耦合 | CanonicalForm |
契约规范
- 输入契约:使用强类型参数,避免
object或Dictionary - 输出契约:使用明确定义的返回类型,避免
dynamic或object - 异常契约:明确声明可能抛出的异常类型
- 生命周期契约:明确方法的可重复调用性和线程安全性
反模式对照→ 循环聚合(聚合间循环依赖)
四、聚合的测试策略
聚合点的测试策略与其职责相关:
| 聚合类型 | 测试策略 | 核心验证点 |
|---|---|---|
| 输入聚合 | Mock 内部依赖,验证输入转换正确 | 输入是否被正确处理 |
| 输出聚合 | Mock 外部资源,验证输出正确 | 输出是否按契约生成 |
| 能力聚合 | Mock 所有内部实现,验证转发正确 | 转发是否完整、参数是否正确 |
| 管线聚合 | Mock 所有 System,验证编排顺序 | 步骤顺序是否正确、异常是否传播 |
测试金字塔
╱╲ ╱ ╲ 聚合集成测试(验证聚合点间的协作) ╱ ╲ ╱──────╲ 聚合单元测试(验证单个聚合点的行为) ╱────────╲ 内部实现测试(验证聚合内部的实现细节)五、聚合的演化与重构
聚合架构不是一成不变的,随着系统的演化,聚合点也需要重构:
聚合点演化的信号
| 信号 | 问题 | 解决方案 |
|---|---|---|
| 聚合点方法过多(>20) | 职责过重 | 拆分为多个聚合点 |
| 聚合点频繁修改 | 职责不稳定 | 提取稳定的核心接口 |
| 聚合点绕过频繁 | 边界不合理 | 重新划分边界 |
| 聚合点测试困难 | 依赖过多 | 提取接口,依赖注入 |
聚合点重构的步骤
- 识别:通过上述信号识别需要重构的聚合点
- 提取:提取稳定的接口作为新契约
- 迁移:逐步将调用方迁移到新契约
- 废弃:标记旧聚合点为
[Obsolete] - 删除:确认无调用方后删除旧聚合点
第三部分:聚合架构的实现模式
本部分回答:聚合在代码层面长什么样?三种模式如何选择?
模式一:三收拢点模式
1.1 模式概述
三收拢点模式是 FrontEndDriven 模块引入的核心架构模式。其设计思想是:
在 ECS 渲染管线中,所有数据流入、状态流出、控件操作都必须经过三个明确定义的收拢点,不允许绕过。
三个收拢点构成一个完整的"输入-处理-输出"闭环:
外部数据 → ① EcsInputPort → [ECS World] → ② CsgEntryPoint → ③ WinFormsOutputPort → 控件1.2 三个收拢点的职责
| 收拢点 | 拓扑类型 | 职责 | 设计约束 |
|---|---|---|---|
| EcsInputPort | 点聚合 | 所有数据输入的唯一点 | 只更新 Component,不操作控件 |
| CsgEntryPoint | 点聚合 | 所有状态输出的唯一点 | 只读取 Component,不修改状态 |
| WinFormsOutputPort | 点聚合 | 所有控件操作的唯一点 | 只执行差异更新,不创建控件 |
1.3 模式的核心设计决策
为什么需要三个收拢点而不是一个?
这是单一职责原则在聚合架构中的体现:
- 如果用一个收拢点同时处理输入和输出,输入逻辑的变更可能影响输出逻辑
- 如果用一个收拢点同时处理状态收集和控件操作,状态收集的变更可能影响控件操作
- 三个收拢点各自独立演化,互不干扰
为什么 CsgEntryPoint 和 WinFormsOutputPort 要分离?
这是关注点分离的体现:
CsgEntryPoint关注"当前状态是什么"(读)WinFormsOutputPort关注"如何将状态同步到控件"(写)- 两者通过
CanonicalForm数据对象通信,互不依赖
1.4 模式的设计收益
| 维度 | 分散架构 | 三收拢点架构 |
|---|---|---|
| 数据流可审计性 | 数据流路径不明确 | 所有数据流经过三个收拢点 |
| 控件操作可控性 | 操作散落各处 | 所有操作经过 WinFormsOutputPort |
| 可测试性 | 需要真实控件环境 | 可以 Mock 收拢点接口 |
| 可替换性 | 替换 WinForms 需修改所有 System | 只需替换 WinFormsOutputPort |
| 状态一致性 | 无统一状态收集 | CsgEntryPoint 提供完整快照 |
模式二:统一调用入口模式
2.1 模式概述
统一调用入口模式是 WorkFlowMethod 模块采用的架构模式。其设计思想是:
将一个模块的所有公开能力收敛到一个统一的静态入口类中,外部调用方只需引用这一个类即可访问模块的全部功能。
2.2 模式的核心设计决策
为什么使用静态入口而不是实例入口?
这是一个便捷性与可测试性的权衡:
| 维度 | 静态入口 | 实例入口 |
|---|---|---|
| 使用便捷性 | 无需创建实例,直接调用 | 需要先创建或注入实例 |
| 可测试性 | 难以 Mock,依赖静态状态 | 易于 Mock,依赖注入 |
| 状态管理 | 全局静态状态 | 实例状态,生命周期可控 |
| 适用场景 | 工具类、基础设施 | 有状态服务、可替换实现 |
WorkFlowMethod 的解决方案:混合模式——无状态操作使用静态委托,有状态操作使用工厂方法,全局状态通过 DI 容器管理。
2.3 模式的设计约束
- 入口层应该薄:只做转发,不包含业务逻辑
- 入口层应该全:覆盖模块的所有公开能力
- 入口层应该稳:接口稳定,内部实现可以变化
模式三:管线聚合模式
3.1 模式概述
管线聚合模式是将多个 System 的执行编排到一个管线中,通过统一的ExecutePipeline()方法对外暴露。其设计思想是:
将一组有序的执行步骤封装为一个管线,外部调用方只需调用一个方法即可触发完整的处理流程。
3.2 模式的核心设计决策
为什么需要管线聚合而不是直接调用各个 System?
- 编排逻辑集中:System 的执行顺序、条件判断、异常处理都在一个地方
- 外部调用简化:外部只需调用一个方法,不需要了解内部 System 的细节
- 增量执行:通过脏标记(Dirty Flag)机制,避免无变更时的重复执行
System 之间如何解耦?
每个 System 只操作 Component,不直接依赖其他 System:
System A 写入 Component X System B 读取 Component X(不依赖 System A) System C 读取 Component X(不依赖 System A 或 B)这种设计使得 System 可以独立测试、独立替换、独立演化。
3.3 脏标记与增量执行
管线聚合引入脏标记机制,避免无变更时的重复执行:
数据变更 → 脏标记 = true → 执行管线 → 脏标记 = false 无变更 → 脏标记 = false → 跳过输出脏标记的触发时机:配置加载、事件处理、数据变更。
模式对比与选择指南
| 维度 | 三收拢点模式 | 统一调用入口模式 | 管线聚合模式 |
|---|---|---|---|
| 拓扑结构 | 点聚合 × 3 | 面聚合 | 线聚合 |
| 适用场景 | 子系统边界的数据流收敛 | 模块能力出口收敛 | 执行流程编排 |
| 聚合粒度 | 粗粒度(系统级) | 中粒度(模块级) | 细粒度(流程级) |
| 核心关注点 | 数据流的可审计性 | 能力出口的便捷性 | 执行流程的可控性 |
| 典型问题 | 三个收拢点职责是否清晰 | 入口层是否足够薄 | System 间是否真正解耦 |
选择建议:
- 需要收敛数据流边界→ 三收拢点模式
- 需要收敛模块能力出口→ 统一调用入口模式
- 需要收敛执行流程→ 管线聚合模式
- 三种模式可以组合使用:管线聚合内部包含 System,System 通过统一入口获取能力
第四部分:反模式与演进
本部分回答:聚合设计中有哪些常见错误?聚合架构未来如何发展?
一、聚合架构的常见反模式
1. 上帝聚合(过度聚合)
症状:一个聚合点承担了过多的职责,方法数量超过 30 个,内部实现超过 1000 行。
理论分析:违反了单一职责原则和内聚度要求。上帝聚合的内聚度通常是"逻辑内聚"——元素仅因逻辑分类而聚集,而非功能关联。
解决方案:拆分为多个单一职责的聚合点。
规范对照→ 规范1:单一职责
2. 分散聚合(聚合不足)
症状:应该聚合的操作分散在多个地方,没有统一的入口。
理论分析:违反了收敛度要求。分散聚合的收敛度低(<50%),聚合点形同虚设。
解决方案:创建统一的输出聚合点,将所有操作收敛到该点。
规范对照→ 规范2:边界内完整
3. 隐式聚合(无明确边界)
症状:聚合点存在,但边界不明确,外部调用方不清楚哪些操作属于聚合内部。
理论分析:违反了边界清晰度要求。隐式聚合的边界模糊,导致外部调用方难以判断哪些操作应该通过聚合点。
解决方案:明确每个聚合点的边界,不允许越界操作。
规范对照→ 规范3:边界间无重叠
4. 循环聚合(聚合间循环依赖)
症状:聚合点 A 依赖聚合点 B,聚合点 B 又依赖聚合点 A。
理论分析:循环依赖破坏了聚合的独立性,使得两个聚合点无法独立演化。
解决方案:引入事件/委托打破循环依赖。
规范对照→ 聚合间通信契约
二、聚合架构的未来演进
聚合架构不是一种固定的模式,而是一种持续演进的工程实践。以下是三个演进方向:
方向一:从手动聚合到自动聚合
当前的聚合点需要手动维护。未来可以通过代码生成、AOP 或 Source Generator 自动生成聚合点的代码,减少手动维护成本。
方向二:从静态聚合到动态聚合
当前的聚合点在编译时就已经确定。未来可以通过配置驱动的方式,在运行时动态组合聚合点,实现更灵活的架构。
方向三:从单层聚合到多层聚合
当前的聚合点主要关注单层架构。未来可以在多个层级上建立聚合点,形成聚合的层次化结构:
应用层聚合 → 领域层聚合 → 基础设施层聚合核心思想
让隐式的依赖变得显式,让分散的操作变得集中,让混乱的边界变得清晰。