← 返回题目列表

策略模式和模板方法模式有什么区别?

高频 中等 第 5 / 26 题 更新于 2026/07/28
策略模式模板方法模式组合继承

简化版

策略模式通过组合切换不同算法,调用方可以运行时选择策略;模板方法模式通过继承固定算法骨架,把某些步骤延迟给子类实现。简单记:策略模式换整个算法,模板方法固定流程、替换步骤。

详细版

两者都能复用逻辑、封装变化,但解决角度不同。

策略模式:

  • 依赖组合;
  • 多个策略实现同一个接口;
  • 可以在运行时切换;
  • 适合“多套算法互相替换”。

模板方法模式:

  • 依赖继承;
  • 父类定义固定流程;
  • 子类重写其中某些步骤;
  • 适合“流程骨架稳定,局部步骤变化”。

比如不同支付方式整体流程差异较大,可以用策略模式;如果所有导入任务都遵循“读取文件、校验、转换、保存、通知”的固定流程,只是校验和转换细节不同,可以用模板方法模式。

完整版教学

一、先从代码结构看差异

策略模式的结构通常是:

Context -> Strategy 接口 -> 多个 ConcreteStrategy

它强调组合。上下文持有一个策略对象,把可变算法委托给策略。

模板方法模式的结构通常是:

AbstractClass 定义 templateMethod()
  -> 子类覆盖 step1 / step2

它强调继承。父类控制整体流程,子类只能改父类允许它改的步骤。

二、策略模式是替换一整套行为

策略模式适合多种算法之间整体可替换。

以报价系统为例:

  • 普通客户报价;
  • VIP 客户报价;
  • 大客户协议价;
  • 活动促销价。

每种报价规则可能计算方式完全不同。主流程只需要拿到报价策略并调用:

QuoteStrategy strategy = factory.get(customerType);
return strategy.quote(order);

策略之间通常是平级关系,没有谁规定谁的执行步骤。

三、模板方法模式是固定流程骨架

模板方法适合流程顺序稳定、部分步骤变化的场景。

比如文件导入:

public final void importData() {
    readFile();
    validate();
    transform();
    save();
    notifyResult();
}

不同文件类型可能有不同校验和转换逻辑,但整体流程不能乱。父类把骨架固定住,子类只实现变化步骤。

这类场景如果用策略模式也能做,但会弱化“流程顺序必须固定”的约束。

四、运行时切换能力不同

策略模式天然支持运行时切换。一个上下文可以根据参数选择不同策略,也可以在运行过程中替换策略对象。

模板方法模式的行为更多在类层次上确定。你创建了哪个子类,对应流程里的可变步骤就确定了。虽然也能通过多态选择不同子类,但它不像策略模式那样强调动态替换。

所以如果面试官问“哪个更灵活”,通常可以说:策略模式在运行时组合和替换方面更灵活;模板方法在流程约束和代码复用方面更强。

五、组合优先还是继承优先

现代工程里经常强调“组合优于继承”。策略模式符合这个思想,因为它把行为作为对象组合进来。

模板方法依赖继承,优点是流程复用直接,缺点是父子类耦合较强。父类改动可能影响所有子类,子类也容易被父类的钩子方法限制。

但这不代表模板方法不好。如果业务确实有稳定流程骨架,它非常合适。设计模式的选择应该看问题,不是看哪个更流行。

六、组合替换与继承骨架的取舍

有 4 套可整体替换算法时策略可注入 4 个实现;固定 5 步流程只允许其中 2 步变化时,模板方法更直接。

strategy: Context -> replace whole behavior; template: base skeleton -> override hooks

这个推演把模式带来的收益和成本放在同一条调用链上。设计评审时既要确认结果正确,也要确认额外层次没有改变原有契约。

七、边界、代价与验证

检查维度应确认的内容
正确性不要只背“组合对继承”,要结合变化粒度:整体算法替换还是固定骨架中的局部步骤。
适用边界策略支持运行时组合且避免继承耦合;模板方法能强制复用流程顺序,但受单继承和覆写边界约束。
测试证据覆盖正常路径、异常路径、空值或未知类型,并断言调用次数与顺序
运行成本记录额外对象、调用层数、延迟、线程或内存开销,不用模式名称代替测量

模式落地后要用单元测试验证独立职责,用集成测试验证对象装配和真实调用入口。涉及并发、远程或异步时,还要补充竞态、超时、重复执行与资源释放测试。

易错点:不要只背“组合对继承”,要结合变化粒度:整体算法替换还是固定骨架中的局部步骤。

八、常见误区与追问

  • 误区:模板方法也能换子类,所以和策略完全相同。 模板依赖继承并固定骨架,策略通过对象组合替换行为,生命周期和扩展方式不同。
  • 误区:用了策略模式,系统里就不该再出现任何条件判断。 策略消除的是反复扩张的业务算法分支;选择策略、校验输入和兜底仍可能需要有限判断。
  • 误区:示例代码能运行,就代表模式边界设计正确。 能运行只证明一条路径,仍要检查异常、并发、顺序、生命周期以及新增实现时是否修改稳定代码。
  • 追问:两种模式可以一起使用吗? 可以;模板固定大流程,其中某一步再委托可替换策略。
  • 追问:策略对象可以保存本次请求的可变状态吗? 容器单例策略通常不应保存请求状态,应把订单、用户等数据作为参数传入,否则并发调用会相互污染。
  • 追问:怎样验证这套设计没有改变原有语义? 先做基线行为测试,再对新增层验证返回值、异常类型、调用次数和顺序;性能敏感处还要比较改造前后的量化指标。

九、加强记忆

策略模式和模板方法模式的区别记成“组合换算法,继承定流程”。策略模式适合多套算法运行时切换;模板方法适合流程骨架固定、局部步骤变化,并且希望由父类控制执行顺序的场景。