济南市网站建设_网站建设公司_jQuery_seo优化
2025/12/20 20:48:12 网站建设 项目流程

策略模式(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)。
    • 模板层:近战策略 内部,攻击流程是:举起武器 -> 挥舞(可变) -> 造成伤害。这又是一个模板方法。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询