当前位置: 首页 > news >正文

模板和策略模式的区别

策略模式(Strategy)和模板方法模式(Template Method)是面试中“撞车率”最高的两个模式。它们都在解决“算法封装”“扩展性”的问题,代码看起也很像(都用了多态),但本质截然不同。

一句话总结核心区别:

策略模式是“换脑子”(组合/整体替换),模板模式是“填空题”(继承/局部定制)。


1. 核心维度的深度对比

维度 模板方法模式 (Template Method) 策略模式 (Strategy Pattern)
复用机制 继承 (Inheritance) 组合 (Composition)
关系 Is-A (子类是父类的一种) Has-A (Context 持有一个 Strategy)
灵活性 (编译期决定,对象创建后无法改变行为) (运行期决定,随时可以用 SetXXX 切换)
算法粒度 部分定制 (大流程不变,只改小步骤) 整体替换 (整个算法逻辑全部换掉)
控制权 父类控制子类 (好莱坞原则) 客户端选择具体策略 (委托机制)
修改成本 需要修改继承树,耦合度相对较高 新增类即可,无需修改 Context,耦合极低

2. 代码结构的直观差异 (C++ 视角)

A. 模板方法:填空题

  • 场景: 泡茶和泡咖啡。
  • 逻辑: 烧水 -> (放入原料) -> 倒水 -> (加调料)
  • 特点: 流程是死的,具体放什么原料是留空的。、
class Beverage { // 模板
public:// 流程被父类“锁死”了,子类动不了void MakeBeverage() {BoilWater();Brew();      // 填空 APourInCup();AddCondiments(); // 填空 B}
protected:virtual void Brew() = 0;          // 留给子类实现virtual void AddCondiments() = 0; // 留给子类实现
private:void BoilWater() { ... } // 公用逻辑void PourInCup() { ... } // 公用逻辑
};// 使用:一旦你 new Tea(),它这辈子就是茶,变不成咖啡
Beverage* b = new Tea(); 
b->MakeBeverage();

B. 策略模式:换脑子

  • 场景: 手机导航。
  • 逻辑: 给我规划一条路。
  • 特点: 我不管中间步骤(怎么左转怎么右转),我只关注整体算法的选择(是走最短路径,还是走最少收费)。
class IRouteStrategy { // 策略接口
public:virtual void BuildRoute() = 0;
};class Navigator { // 上下文IRouteStrategy* strategy; // 持有接口
public:void SetStrategy(IRouteStrategy* s) { strategy = s; }void Build() { strategy->BuildRoute(); } // 委托
};// 使用:随时可以切
Navigator nav;
nav.SetStrategy(new FastestRoute()); // 只要快
nav.Build();
nav.SetStrategy(new CheapestRoute()); // 没钱了,换省钱路线
nav.Build();

3. 生动比喻

  • 模板方法模式 就像 “做试卷”
    • 试卷的题目(算法骨架)是老师印好的,不能改。
    • 你只能在括号里填上你的答案(子类重写虚函数)。
    • 你不能把语文卷子变成数学卷子。
  • 策略模式 就像 “USB 插拔”
    • 电脑(Context)有一个 USB 接口。
    • 你可以插 U 盘(策略A),也可以插 鼠标(策略B),也可以插 键盘(策略C)。
    • 只要符合 USB 协议(接口),想换什么换什么,想什么时候换就什么时候换。

4. 什么时候用哪个?(选型指南)

模板方法 (Template Method) 当:

  1. 你有一个固定的操作流程,只有其中几个步骤需要变化。
  2. 你想把公共的代码抽离到父类中,避免代码重复。
  3. 核心在于: 你想控制子类的行为流程(父类是导演)。

策略模式 (Strategy) 当:

  1. 你需要动态地切换算法(比如游戏里换武器,商城里换打折方案)。
  2. 你有许多相似的类,唯一的区别只是它们解决问题的方式(算法)不同。
  3. 你想隐藏算法的具体实现细节,只暴露一个接口。
  4. 核心在于: 你想让算法独立于使用它的客户而变化(彻底解耦)。

5. 高级思考:两者能结合吗?

能!而且非常常见。

在策略模式的具体策略类内部,为了实现那个具体的算法,可能会使用模板方法模式。

  • 例子:
    • 策略层: 游戏中有 近战策略远程策略(Strategy)。
    • 模板层:近战策略 内部,攻击流程是:举起武器 -> 挥舞(可变) -> 造成伤害。这又是一个模板方法。

总结: 策略模式是大局观(整体替换),模板模式是微操(细节定制)。

http://www.jsqmd.com/news/115834/

相关文章:

  • 好友圈模块 Cordova 与 OpenHarmony 混合开发实战
  • 学Simulink——机器人控制场景实例:基于Simulink的SCARA机械臂关节空间PD控制仿真
  • 第4章 运算符
  • 工厂模式和抽象工厂模式的区别
  • 洞察:MCP与Function Calling区别
  • 一文搞懂DNAT与SNAT:内网外网通信的“流量翻译官”
  • 3D打印与低压灌注硅胶复模小批量零件生产制造
  • 快!太快了!一键生成!一键导出!微信自动统计数据报表来了!
  • 抽象工厂
  • 对比:字节DeerFlow与阿里DeepResearch
  • 电路板维修
  • 设计模式的概念
  • 【后端开发笔记】JVM底层原理-垃圾回收篇 - 指南
  • 备份恢复模块 - Cordova与OpenHarmony混合开发实战
  • 第2章 变量和基本类型
  • 基于记忆增强网络的语言模型推理优化
  • 对比:Qwen-VL与传统的CNN在图像处理应用
  • 线程五种状态
  • 导入导出模块 - Cordova与OpenHarmony混合开发实战
  • 【硬件设计】DC12V输入的防护+滤波设计
  • 洞察:阿里通义DeepResearch 技术
  • 年前“催婚大作战”,用“技术思维”解决婚恋问题
  • 160. 相交链表
  • insert/update 注入
  • Matlab BP分类 设计神经网络 输入层,隐含层,输出层 可以应用于故障诊断 故障分类
  • 数据采集个人博客——途知旅行助手路径规划算法选择与api调用实现
  • 红黑树
  • 账户增删改查与余额统计 Cordova 与 OpenHarmony 混合开发实战
  • 推荐分享 - Cordova 与 OpenHarmony 混合开发实战
  • 【少走弯路】上海进出口权办理流程及费用?出口经营权的申请步骤? - 速递信息