通俗且详细讲解模板方法模式

文章目录

    • [🎯 什么是模板方法模式?一个生动的比喻](#🎯 什么是模板方法模式?一个生动的比喻)
    • [☕ 真实生活案例:咖啡厅的饮料制作](#☕ 真实生活案例:咖啡厅的饮料制作)
    • [💻 C++代码实现:从菜鸟到高手](#💻 C++代码实现:从菜鸟到高手)
    • [🎪 运行效果:像看话剧一样有趣](#🎪 运行效果:像看话剧一样有趣)
    • [🧩 模板方法模式的四大核心要点](#🧩 模板方法模式的四大核心要点)
      • [1. **框架固定,细节灵活**](#1. 框架固定,细节灵活)
      • [2. **好莱坞原则:"不要调用我们,我们会调用你"**](#2. 好莱坞原则:"不要调用我们,我们会调用你")
      • [3. **代码复用最大化**](#3. 代码复用最大化)
      • [4. **便于维护和扩展**](#4. 便于维护和扩展)
    • [🌟 实际应用场景(不只是饮料!)](#🌟 实际应用场景(不只是饮料!))
    • [📊 模板方法模式 vs 普通继承:有什么区别?](#📊 模板方法模式 vs 普通继承:有什么区别?)
    • [🎁 设计模式的"秘密武器"](#🎁 设计模式的"秘密武器")
      • [钩子方法(Hook Method):给子类留的"后门"](#钩子方法(Hook Method):给子类留的"后门")
    • [🚀 为什么要学模板方法模式?](#🚀 为什么要学模板方法模式?)
    • [💡 总结:记住这三个关键词](#💡 总结:记住这三个关键词)

🎯 什么是模板方法模式?一个生动的比喻

想象你是一个大厨,要教两个徒弟做菜:一个学做红烧肉,一个学做清蒸鱼。

虽然两道菜完全不同,但烹饪的基本流程却是相通的:

  1. 准备食材 → 2. 预处理 → 3. 烹饪 → 4. 装盘调味

这个固定的流程就是"模板",而每一步的具体操作就是"方法"。模板方法模式就是:定义一个算法的骨架,让某些步骤由子类去具体实现

☕ 真实生活案例:咖啡厅的饮料制作

让我们走进一家咖啡厅,看看他们如何高效制作不同饮料:

咖啡师小张的工作流程:

  • 🔥 烧开水(必做)
  • ☕ 冲泡咖啡粉(咖啡特有)
  • 🥛 倒入杯中(必做)
  • 🍬 加糖和牛奶(咖啡特有)

茶艺师小李的工作流程:

  • 🔥 烧开水(必做)
  • 🍵 浸泡茶叶(茶特有)
  • 🥛 倒入杯中(必做)
  • 🍋 加柠檬(茶特有)

聪明的店长发现:70%的步骤是重复的! 于是她设计了一个"饮料制作模板"...

💻 C++代码实现:从菜鸟到高手

第一步:创建"饮料制作模板"(抽象基类)

cpp 复制代码
#include <iostream>
#include <memory>
using namespace std;

// 饮料制作模板 - 就像餐厅的标准操作流程
class Beverage {
public:
    // 模板方法:这是核心!定义了不可更改的制作流程
    void prepareRecipe() final {
        cout << "🎬 开始制作饮料..." << endl;
        
        boilWater();        // 第1步:烧水(所有饮料都一样)
        brew();             // 第2步:冲泡(每种饮料不同)
        pourInCup();        // 第3步:倒杯(所有饮料都一样)
        addCondiments();    // 第4步:加料(每种饮料不同)
        
        cout << "✅ 饮料制作完成!" << endl << endl;
    }
    
    // 具体步骤1:烧水(不变的部分)
    void boilWater() {
        cout << "🔥 烧开水中...(等待3分钟)" << endl;
    }
    
    // 具体步骤3:倒入杯中(不变的部分)
    void pourInCup() {
        cout << "🥛 倒入精美的杯子中" << endl;
    }
    
    // 抽象步骤2:冲泡(变化的部分)- 等待子类实现
    virtual void brew() = 0;
    
    // 抽象步骤4:加调料(变化的部分)- 等待子类实现
    virtual void addCondiments() = 0;
    
    virtual ~Beverage() {
        cout << "🧹 清理工作台" << endl;
    }
};

第二步:实现具体的饮料类

cpp 复制代码
// 咖啡类 - 继承自饮料模板
class Coffee : public Beverage {
private:
    string coffeeType;
    
public:
    Coffee(string type = "拿铁") : coffeeType(type) {}
    
    void brew() override {
        cout << "☕ 精心冲泡" << coffeeType << "咖啡粉(专业手法)" << endl;
    }
    
    void addCondiments() override {
        cout << "🍬 加入特制糖浆和新鲜牛奶" << endl;
    }
};

// 茶类 - 继承自饮料模板
class Tea : public Beverage {
private:
    string teaType;
    
public:
    Tea(string type = "绿茶") : teaType(type) {}
    
    void brew() override {
        cout << "🍵 用85°C热水浸泡" << teaType << "茶叶" << endl;
    }
    
    void addCondiments() override {
        cout << "🍋 加入新鲜柠檬片" << endl;
    }
};

// 新增:热巧克力类(展示扩展性)
class HotChocolate : public Beverage {
public:
    void brew() override {
        cout = "🍫 融化高品质巧克力块" << endl;
    }
    
    void addCondiments() override {
        cout << "🧁 加入棉花糖和可可粉装饰" << endl;
    }
};

第三步:让我们"开店营业"!

cpp 复制代码
// 咖啡厅模拟
class CoffeeShop {
public:
    void startBusiness() {
        cout << "🏪 欢迎光临模板方法咖啡厅!" << endl;
        cout << "=================================" << endl;
        
        // 制作咖啡
        cout << "📝 订单1:一位客人点了拿铁咖啡" << endl;
        unique_ptr<Beverage> coffee = make_unique<Coffee>("拿铁");
        coffee->prepareRecipe();
        
        // 制作茶
        cout << "📝 订单2:一位客人点了龙井茶" << endl;
        unique_ptr<Beverage> tea = make_unique<Tea>("龙井");
        tea->prepareRecipe();
        
        // 制作热巧克力
        cout << "📝 订单3:小朋友点了热巧克力" << endl;
        unique_ptr<Beverage> chocolate = make_unique<HotChocolate>();
        chocolate->prepareRecipe();
        
        cout << "=================================" << endl;
        cout << "🎉 今天的营业结束,感谢使用模板方法模式!" << endl;
    }
};

int main() {
    CoffeeShop shop;
    shop.startBusiness();
    return 0;
}

🎪 运行效果:像看话剧一样有趣

复制代码
🏪 欢迎光临模板方法咖啡厅!
=================================
📝 订单1:一位客人点了拿铁咖啡
🎬 开始制作饮料...
🔥 烧开水中...(等待3分钟)
☕ 精心冲泡拿铁咖啡粉(专业手法)
🥛 倒入精美的杯子中
🍬 加入特制糖浆和新鲜牛奶
✅ 饮料制作完成!
🧹 清理工作台

📝 订单2:一位客人点了龙井茶
🎬 开始制作饮料...
🔥 烧开水中...(等待3分钟)
🍵 用85°C热水浸泡龙井茶叶
🥛 倒入精美的杯子中
🍋 加入新鲜柠檬片
✅ 饮料制作完成!
🧹 清理工作台

📝 订单3:小朋友点了热巧克力
🎬 开始制作饮料...
🔥 烧开水中...(等待3分钟)
🍫 融化高品质巧克力块
🥛 倒入精美的杯子中
🧁 加入棉花糖和可可粉装饰
✅ 饮料制作完成!
🧹 清理工作台

=================================
🎉 今天的营业结束,感谢使用模板方法模式!

🧩 模板方法模式的四大核心要点

1. 框架固定,细节灵活

  • 🏗️ 父类定义"做什么"(算法骨架)
  • 🎨 子类定义"怎么做"(具体实现)

2. 好莱坞原则:"不要调用我们,我们会调用你"

父类对子类说:"你只管实现具体步骤,什么时候调用由我来决定!"

3. 代码复用最大化

相同的代码(烧水、倒杯)只写一次,避免"复制粘贴"的罪恶

4. 便于维护和扩展

要修改流程?只需改父类!要新增饮料?只需继承!

🌟 实际应用场景(不只是饮料!)

场景1:游戏开发

cpp 复制代码
// 所有游戏都有:初始化→主循环→清理
class Game {
    void run() final {  // 模板方法
        initialize();
        while(!isGameOver()) {
            update();
            render();
        }
        cleanup();
    }
    // 具体游戏实现抽象方法...
};

场景2:文档处理

cpp 复制代码
// 所有文档处理:打开→读取→转换→保存
class DocumentProcessor {
    void process() final {
        openFile();
        readContent();
        convertFormat();  // 不同格式不同实现
        saveFile();
    }
};

场景3:测试框架

cpp 复制代码
// 测试用例模板:准备→执行→验证→清理
class TestCase {
    void runTest() final {
        setUp();
        executeTest();
        verifyResult();
        tearDown();
    }
};

📊 模板方法模式 vs 普通继承:有什么区别?

特性 普通继承 模板方法模式
代码复用 部分复用 最大化复用
流程控制 子类控制 父类控制
扩展性 一般 容易扩展
规范性 随意 标准化

🎁 设计模式的"秘密武器"

钩子方法(Hook Method):给子类留的"后门"

cpp 复制代码
class Beverage {
protected:
    // 钩子方法:子类可以选择是否重写
    virtual bool customerWantsCondiments() {
        return true;  // 默认加调料
    }
    
    void prepareRecipe() final {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {  // 使用钩子
            addCondiments();
        }
    }
};

class BlackCoffee : public Beverage {
protected:
    bool customerWantsCondiments() override {
        return false;  // 黑咖啡不加调料
    }
};

🚀 为什么要学模板方法模式?

对初学者:

  • 📚 理解面向对象:封装、继承、多态的完美结合
  • 🧠 培养设计思维:从"怎么写代码"到"怎么设计代码"

对职场人:

  • 💼 提高代码质量:减少bug,提高可维护性
  • ⏱️ 提升开发效率:避免重复造轮子

对架构师:

  • 🏗️ 构建稳定架构:创建可扩展的系统框架
  • 🔄 统一开发规范:团队协作更加顺畅

💡 总结:记住这三个关键词

  1. 模板 - 定义不变的算法骨架
  2. 方法 - 提供可变的具体实现
  3. 模式 - 解决特定问题的经验总结

下次当你发现多个类有相似流程时,记得想想:"这里能不能用模板方法模式?"

就像那位聪明的咖啡店长一样,用智慧的设计让代码变得更加优雅和高效!🎯


💡 小练习:你能用模板方法模式设计一个"文件导出工具"吗?支持导出PDF、Excel、Word格式,它们都有:准备数据→格式化→保存文件 的流程。

相关推荐
口袋物联1 小时前
模板方法模式在 C 语言中的应用(含 Linux 内核实例)
linux·c语言·模板方法模式
reddingtons5 小时前
Magnific AI:拒绝“马赛克”?AI 幻觉重绘流,拯救 1024px 废片
图像处理·人工智能·设计模式·新媒体运营·aigc·设计师·教育电商
知无不研6 小时前
c++的设计模式(常用)
c++·观察者模式·单例模式·设计模式·简单工厂模式
李广坤9 小时前
设计模式的本质:隔离变化
后端·设计模式
河码匠12 小时前
设计模式之依赖注入(Dependency Injection)
java·设计模式·log4j
小湘西14 小时前
互联网黑话持续更新
其他·设计模式
a35354138214 小时前
设计模式——访问者模式
设计模式·访问者模式
Eloudy14 小时前
动态库中不透明数据结构的设计要点总结
数据结构·设计模式
mCell1 天前
为什么 Memo Code 先做 CLI:以及终端输入框到底有多难搞
前端·设计模式·agent