
本文介绍如何将顺序依赖、分支可选的旧式过程化算法,优雅重构为可维护、可扩展的面向对象结构,重点解决方法跳过逻辑复用、职责分离与执行流程解耦问题。
本文介绍如何将顺序依赖、分支可选的旧式过程化算法,优雅重构为可维护、可扩展的面向对象结构,重点解决方法跳过逻辑复用、职责分离与执行流程解耦问题。
在面向对象重构中,将线性、条件跳转的过程化算法(如初始化 → 数据暂存 → 多源数据注入 → 排序 → 输出准备)直接映射为继承树(如抽象基类 + 多个子类重写 execute())往往导致三类问题:执行逻辑重复、条件判断散落、扩展成本高。更优解是采用“策略化流程编排”——将算法视为可配置的步骤序列,由统一调度器驱动,各步骤自主决定是否执行,而非由调用方硬编码分支。
✅ 推荐结构:责任链 + 策略步骤 + 流程引擎
核心思想:每个处理阶段封装为独立策略对象(Strategy),流程控制器(Engine)按预设顺序调用,每个策略自行评估前置条件并决定是否执行。这彻底消除重复的 if-else 调度逻辑,且新增用例只需注册新步骤序列,无需修改原有类。
示例实现(Java)
// 步骤接口:每个步骤可自检条件并执行
interface ProcessingStep {
boolean shouldExecute(Context context); // 条件判断委托给步骤自身
void execute(Context context);
}
// 上下文承载共享状态与初始条件
class Context {
final InitialCondition condition;
Object data; // 可为 List<Map<String, Object>> 等通用容器
public Context(InitialCondition condition) { this.condition = condition; }
}
// 具体步骤实现(职责单一、条件内聚)
class InitializeVariablesStep implements ProcessingStep {
public boolean shouldExecute(Context c) { return true; } // 总是执行
public void execute(Context c) { c.data = new ArrayList<>(); }
}
class AddDataFromDraftStep implements ProcessingStep {
public boolean shouldExecute(Context c) {
return c.condition.hasDraft(); // 条件判断内聚于此
}
public void execute(Context c) { /* 从 draft 加载 */ }
}
class AddDataFromExternalSourceStep implements ProcessingStep {
public boolean shouldExecute(Context c) {
return c.condition.isExternalSourceEnabled();
}
public void execute(Context c) { /* 调用外部 API */ }
}
// 流程引擎:无业务逻辑,仅负责顺序调度
class ProcessingEngine {
private final List<ProcessingStep> steps;
public ProcessingEngine(List<ProcessingStep> steps) {
this.steps = steps;
}
public void execute(Context context) {
for (ProcessingStep step : steps) {
if (step.shouldExecute(context)) {
step.execute(context);
}
}
}
}
// 按用例组装不同流程(开闭原则:新增用例不改代码,只配新列表)
var useCase1 = List.of(
new InitializeVariablesStep(),
new SaveTemporaryDataStep(),
new AddDataFromExternalSourceStep(),
new SortDataStep(),
new PrepareOutputStep()
);
var useCase2 = List.of(
new InitializeVariablesStep(),
new SaveTemporaryDataStep(),
new AddDataFromDraftStep(), // 替换第三步
new AddDataFromExternalSourceStep(), // 第四步仍保留
new SortDataStep(),
new PrepareOutputStep()
);
new ProcessingEngine(useCase1).execute(new Context(condition));⚠️ 关键注意事项
- 避免“空检查式跳过”反模式:原答案中 if(draft != null) addDataFromDraft() 将条件判断与调用强耦合,违反单一职责;应将条件判断上移至步骤自身(shouldExecute()),确保步骤自治。
- 上下文设计需谨慎:Context 应仅包含必要共享状态,避免膨胀为“万能参数包”。推荐使用 Builder 模式构造,或按领域拆分为 DataContext/ConfigContext 等子类。
- 调试友好性:在 ProcessingEngine.execute() 中添加日志(如 log.debug("Executing: {}", step.getClass().getSimpleName())),便于追踪实际执行路径。
- 异常处理策略:建议步骤抛出领域异常(如 DataValidationException),由引擎统一捕获并记录失败步骤,而非静默吞掉错误。
✅ 总结
重构此类算法的本质,是从“谁来决定执行什么”转向“每个步骤自己回答是否该执行”。通过策略接口 + 上下文 + 流程引擎三层结构,你获得:
? 高内聚(每步骤封装自身逻辑与条件)
? 低耦合(引擎不依赖具体步骤实现)
? 易扩展(新增用例 = 新建步骤 + 新建步骤列表)
? 可测试(每个步骤可独立单元测试,引擎可模拟步骤验证调度)
放弃“一个 execute 方法写满 if-else”的继承方案,拥抱声明式流程编排——这才是 OOP 在算法重构中的真正力量。










