🔄 回顾 Day 9:命令模式要点
在 Day 9 中,我们学习了命令模式(Command Pattern):
- 用于将“请求”封装为对象,实现请求与执行者的解耦。
- 可支持操作的撤销、重做、批量执行等复杂行为控制。
- 在遥控器控制、任务队列、UI 事件系统中广泛应用。
而今天的模板方法模式,强调的是:
在一个抽象流程中定义“固定结构”,而将可变步骤交给子类来实现。
一、模板方法模式是什么?
模板方法模式(Template Method Pattern)是一种行为型设计模式,用于:
- 定义一套算法骨架,在抽象类中写好执行流程
- 让子类去“定制”部分步骤(而不是整体流程)
✅ 关键点:
不变的流程 + 可变的步骤
二、适用场景
场景类型 | 示例描述 |
---|---|
流程固定的算法骨架 | 报表导出流程、文档解析、代码生成等 |
钩子函数调用场景 | 操作系统回调、生命周期钩子 |
多子类复用共同行为 | 数据抓取流程、文件处理、协议接入 |
三、结构图(UML)
+---------------------+
| AbstractClass |
+---------------------+
| +templateMethod() |
| +step1() |
| +step2() |
+---------------------+
/\
/ \
+-------------------+ +-------------------+
| ConcreteClassA | | ConcreteClassB |
+-------------------+ +-------------------+
| +step2() override | | +step2() override |
+-------------------+ +-------------------+
四、C++ 实现:数据导出系统
我们实现一个数据导出器:支持将数据导出为 CSV、JSON 两种格式。
✅ 抽象模板类
class DataExporter {
public:
void exportData() {
readData();
formatData();
writeToFile();
}
virtual ~DataExporter() = default;
protected:
virtual void readData() {
std::cout << "读取原始数据..." << std::endl;
}
virtual void formatData() = 0; // 子类必须实现
virtual void writeToFile() {
std::cout << "写入文件完成。" << std::endl;
}
};
✅ 子类实现(CSV 导出器)
class CsvExporter : public DataExporter {
protected:
void formatData() override {
std::cout << "格式化为 CSV 格式..." << std::endl;
}
};
✅ 子类实现(JSON 导出器)
class JsonExporter : public DataExporter {
protected:
void formatData() override {
std::cout << "格式化为 JSON 格式..." << std::endl;
}
};
✅ 使用代码
int main() {
std::unique_ptr<DataExporter> exporter;
exporter = std::make_unique<CsvExporter>();
exporter->exportData();
exporter = std::make_unique<JsonExporter>();
exporter->exportData();
return 0;
}
五、特点总结:优点与缺点
✅ 优点:
- 代码复用性高:流程写一遍,子类共享结构
- 扩展灵活:只需重写步骤函数即可扩展新行为
- 强制执行顺序:子类无法篡改流程结构
❗ 缺点:
- 增加类数量(每种行为都要写个子类)
- 对子类开发者要求较高(必须理解父类结构)
六、实战场景参考
场景名称 | 模板流程说明 |
---|---|
报表导出引擎 | 读取数据 → 格式化 → 输出 CSV/JSON/Excel |
编译器前端 | 词法分析 → 语法分析 → 语义分析 → 生成中间码 |
网络协议处理 | 接收请求 → 校验 → 解包 → 应答 |
游戏生命周期 | Init → Start → Update → Destroy |
业务模板系统 | 加载配置 → 数据处理 → 日志记录 |
七、与策略模式的对比回顾
模式 | 模板方法模式 | 策略模式 |
---|---|---|
目的 | 固定流程 + 可定制步骤 | 动态切换算法 |
调用者角色 | 调用方始终调用 templateMethod() |
外部显式切换策略对象 |
子类行为控制力 | 只允许重写“步骤”,流程固定 | 每个策略完全独立 |
八、面试回答模板
“我们有一套导出系统使用模板方法模式设计。父类封装了导出的主流程,子类如 CsvExporter 和 JsonExporter 只需要重写格式化步骤。这样可以保证流程的一致性,并方便后期扩展其他格式(如 XML、Excel),而不影响整体框架。”
✅ 加分项:结合生命周期钩子、数据处理框架,强调“一致性 + 定制性”。
九、记忆口诀
“流程归一父类写,细节自留子类做,钩子控制定结构,复用规范皆不破。”
十、明日预告:Day 11
责任链模式(Chain of Responsibility):事件/请求依次传递,灵活组合处理链条,打造解耦的响应系统。