Split Phase 是什么
把「解析输入」与「执行逻辑」拆成两个阶段,中间用一个显式的数据结构承接:第一阶段只负责把各种来源的输入规整成内部结构,第二阶段只面向这个结构做纯逻辑。收益是两段可以独立测试与替换——换输入格式时不动业务,改业务时不必重新理解解析细节。
基本信息
| 适用 | 同一逻辑面对多种输入、输入处理与业务耦合 |
|---|---|
| 中间结构 | 显式的数据对象(订单请求、配置模型、指令) |
| 收益 | 两段可独立测试与替换 |
| 要点 | 第一阶段不做业务判断,第二阶段不做输入解析 |
典型使用场景
- 命令行工具:参数解析成选项对象,业务逻辑只认选项对象
- 接口层:多种报文格式(JSON、XML、CSV)统一转成内部命令
- 批处理:文件读取与字段规整一步,计算与落库另一步
- 规则引擎:把自然语言或配置解析成规则结构,再交由引擎执行
- 测试支持:手工构造中间结构即可覆盖业务分支,不必拼接原始输入
两阶段示例
两阶段示例
// 解析阶段:只做结构归一,不做业务判断,不碰 I/O
OrderRequest structure = structurize(userInput);
// userInput: Map / JSON / 表单,都归一到 OrderRequest
// 执行阶段:纯逻辑,输入输出都是显式结构
OrderResult result = execute(structure, now);
// 好处:
OrderRequest sample = OrderRequest.of(buyer, items, coupon);
assertEquals(expected, execute(sample, fixedNow)); // 免去构造原始输入两个阶段的职责
| 维度 | 解析阶段 | 执行阶段 |
|---|---|---|
| 输入 | 外部原始数据 | 内部中间结构 |
| 输出 | 内部中间结构 | 业务结果 |
| 是否含业务判断 | 不含 | 全部 |
| 测试方式 | 表驱动输入样例 | 构造结构后的断言 |
| 常见错误 | 混入业务校验 | 回头去读原始输入 |
中间结构要按业务语义设计,而不是照抄输入格式:如果中间结构就是原始 JSON 的字段镜像,两段其实还黏在一起,换格式时照样要改执行阶段。
解析阶段可以包含「格式合法性」检查(字段是否存在、类型是否对),但业务规则(额度是否够、状态是否允许)应留在执行阶段,否则同一规则会在两个入口各写一遍。