前面 我们讲了相关的流程引擎概念,现在我们讲投我们在设计流程引擎的时候,我们使用到的哪些设计模式。我们从设计模式的使用上来真正架构一个产品。我们把流程引擎从概念讲到实现。细心的读者可能发现了:每一课里都在出现"模式"——策略模式、模板方法、观察者、门面、适配器…

但我们一直没有系统地讲它们。为什么?

因为设计模式是横向知识。它不是"某一课的内容",而是"贯穿所有课的那条暗线"。你单独看某一课,看到的只是"这里用了策略模式";只有把整个引擎的模式拉出来并列,才能看清:

设计模式不是点缀,而是流程引擎之所以"能扩展、能解耦、能并发"的根本原因。

这个系列,就是把这根暗线抽出来讲透。


一、先看问题:流程引擎难在哪

要理解模式的价值,先理解流程引擎面临的五个核心难题:

难题具体表现
变化点太多审批规则、节点类型、聚合策略、操作动作,每个客户都不一样
状态复杂一条流程有六种状态、多层执行路径、并发分支
流程长一次审批可能跨天跨人,不能用一个长事务包住
要可扩展客户定制不能改核心代码
要可观测每一步都要留痕、可追溯

这五个难题,恰好对应了四个经典的设计模式族。 这不是巧合——流程引擎这类"高度可配置的业务系统",天然就是设计模式的练兵场。


二、模式地图:一张图看懂全局

┌─────────────────────────────────────────────────────────────┐
│                    流程引擎设计模式地图                       │
│                                                             │
│  【难题一】变化点太多 → 扩展解耦组                            │
│     ├─ 策略模式      ── 换算法不改调用方(聚合策略)           │
│     ├─ 工厂+注册表   ── 按名字取实现(原子操作、类型管理)      │
│     ├─ 适配器模式    ── 隔离变化(EngineWire 契约)           │
│     └─ 门面模式      ── 简化复杂度(服务管理器)              │
│                                                             │
│  【难题二】状态复杂 → 流程流转组                              │
│     ├─ 命令模式      ── 把操作对象化(原子操作)              │
│     ├─ 状态模式      ── 用状态驱动行为(六状态机)            │
│     ├─ 组合模式      ── 树形结构统一处理(执行路径树)         │
│     └─ 备忘录模式    ── 保存/恢复现场(同步中断)             │
│                                                             │
│  【难题三/五】要可观测 → 行为扩展组                           │
│     ├─ 观察者模式    ── 事件发布订阅(关键节点广播)           │
│     ├─ 责任链模式    ── 链式处理(监听器链)                  │
│     └─ 模板方法模式  ── 固定骨架、填充细节(操作行为)         │
│                                                             │
│  【难题四】要可扩展 → 结构包装组                              │
│     ├─ 桥接模式      ── 抽象与实现分离(执行路径包裹)         │
│     ├─ 代理模式      ── 中间层增强(节点代理)                │
│     └─ 访问者模式    ── 操作与结构分离(遍历器)              │
└─────────────────────────────────────────────────────────────┘

读图要点:每个分组对应一个难题,每个模式解决难题的一个侧面。它们不是孤立的——同一个功能往往需要几个模式配合(比如聚合策略 = 策略模式 + 观察者模式的两层决策)。


三、四条主线:模式如何协同

3.1 主线一:可扩展性从哪来

客户要定制
    ↓
必须有不改核心就能扩展的地方
    ↓
├─ 定义接口(适配器模式)── EngineWire、ActivityBehaviour
├─ 按名取实现(工厂+注册表)── Operation、TypeManager
├─ 运行时选算法(策略模式)── JoinStrategy
└─ 对外给单一入口(门面模式)── ProcessServiceManager

核心思想:接口定义契约,实现承载变化,注册表负责查找,门面负责收口。

3.2 主线二:状态机怎么驱动

流程要流转
    ↓
必须有清晰的"当前位置"和"下一步"
    ↓
├─ 把流转动作封装成对象(命令模式)── AtomicOperation
├─ 用状态描述位置(状态模式)── ACTIVE/WAITING/ENDING/ENDED
├─ 用树表示并发(组合模式)── 执行路径树
└─ 支持中断恢复(备忘录模式)── 同步事件保存现场

核心思想:状态显式化 + 动作对象化 + 结构树形化 + 现场可恢复。

3.3 主线三:可观测怎么实现

流程要留痕、要能插业务逻辑
    ↓
必须在关键节点"广播"和"拦截"
    ↓
├─ 关键节点发事件(观察者模式)── EngineEvent
├─ 多个监听器依次处理(责任链模式)── IEventListener 链
└─ 统一流程骨架(模板方法)── prepare → execute

核心思想:主线只做核心逻辑,横切逻辑挂在事件上。

3.4 主线四:解耦怎么做

PVM 层要独立于具体引擎实现
    ↓
必须有一层"包裹"和"中介"
    ↓
├─ 抽象与实现分离(桥接模式)── ExecutionWraper
├─ 中间层增强(代理模式)── ProxyNodeDefinition
└─ 遍历与结构分离(访问者模式)── ExecutionVisitor

核心思想:加一层间接,换一份自由。


四、按重要性排序:先学哪些

14 个模式不是同等重要。如果时间有限,按这个顺序学:

优先级模式理由
★★★ 必学策略模式扩展的典型范式,最直观
★★★ 必学命令模式理解"原子操作"的钥匙
★★★ 必学状态模式理解流程流转的钥匙
★★★ 必学观察者模式理解事件驱动的钥匙
★★☆ 重要模板方法理解行为骨架
★★☆ 重要组合模式理解并发分支
★★☆ 重要适配器理解分层解耦
★★☆ 重要工厂+注册表理解扩展注册
★☆☆ 补充门面、责任链、桥接、备忘录、代理、访问者理解细节

前三篇(策略、命令、状态)+ 观察者,是最核心的四个。 掌握了这四个,流程引擎的设计思想就抓住了大半。


五、每篇怎么讲

为了保证系列的一致性,每篇统一用这个结构:

1. 业务问题
   这个模式要解决什么真实问题?(用流程场景讲)
​
2. 模式解法
   模式的核心思想和标准结构是什么?
​
3. 源码证据
   EKP 里怎么用的?贴关键代码,画结构图
​
4. 设计启示
   为什么这么设计?不用模式会怎样?
​
5. 业务价值
   对业务、对交付、对维护意味着什么?

读法建议:先读"业务问题"和"业务价值"两节——它们回答"为什么需要"。技术细节可以快速扫过,需要时再回头细看源码部分。


六、一个重要的提醒

不要为了用模式而用模式。

这 14 个模式之所以出现在流程引擎里,是因为流程引擎真的面临那些难题。如果换一个简单的 CRUD 系统,硬套这些模式,只会让代码更复杂。

判断标准很简单:

当"变化点"反复出现、且每次变化都要改同一处代码时,才需要考虑用模式把那处变化隔离出去。

模式是"应对变化的经验总结",不是"炫技的工具箱"。


七、系列导航

#篇名核心问题
00开篇:模式地图(本篇)全局认识
01策略模式聚合策略如何做到可配可换
02工厂 + 注册表模式引擎如何按名字找到实现
03适配器模式PVM 如何独立于具体引擎
04门面模式复杂引擎如何对外给简单入口
05命令模式原子操作为什么是对象
06状态模式执行路径的六种状态如何驱动行为
07组合模式并行分支为什么用树表示
08备忘录模式同步事件如何保存和恢复现场
09观察者模式事件驱动如何串联整个流程
10责任链模式多个监听器如何依次生效
11模板方法模式操作行为的统一骨架
12桥接模式执行路径为什么要"包裹"
13代理 + 访问者模式中间层与遍历分离

八、业务价值

8.1、看懂"改一处不动全身"的能力从哪来

  业务方最常问:"为什么改个审批规则要等两周?"

  答案往往不是开发慢,而是代码没有为"变化"设计。设计模式让变化点被隔离在独立的位置——改聚合规则不动流程驱动,加操作按钮不动节点逻辑。

  业务价值:需求响应速度。 有模式 = 改一个类;没模式 = 改核心 + 全量回归 + 高风险发版。

  8.2、让"客户定制"不变成"产品失控"

  一套标准产品要卖 100 个客户,每个客户都想改点东西。如果每个改动都往核心代码里塞,产品一年后就没法维护了。

  设计模式提供的是**"扩展位"**——接口、策略、注册表、事件。客户在扩展位上加东西,核心保持干净。

  业务价值:产品可规模化交付。 这是 SaaS/企业软件能否做大的分水岭。

  8.3、降低"人走代码烂"的风险

  设计模式是行业通用语言。"这里用了策略模式",新人三天就能看懂。反面是一个五千行的 if-else,只有原作者能改,他一走代码就烂。

  业务价值:团队可替换性。 人员流动是必然的,代码的"可理解性"决定团队能不能接力。

  8.4、故障定位快,减少业务中断

  模式把职责分清楚了:策略只管算合不合流,Finder 只管找数据,监听器只管发通知。出了问题,日志一看就知道在哪个环节。

  业务价值:故障恢复时间(MTTR)。 定位快一小时,业务就少中断一小时。

  8.5、给技术人一条可复制的成长路径

  对读者(也就是课程受众)来说:

  - 光看概念,模式是空洞的
  - 光看代码,不知道好在哪
  - "问题 → 模式 → 源码 → 启示" 这个结构,给了一条可复制的学习路径

更多推荐