模式定义
定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override 重写)该算法的某些特定步骤。
——《设计模式》GoF
理解:模板方法就是将固定算法流程实现放在父类中实现,将固定流程中的可能变化的步骤定义为虚方法,子类可重写(实现晚绑定)。对于不变的步骤,和算法的实现流程,子类不必关心。子类也不需要关心整个算法实现流程。实现子类的稳定。
示例
整个代码框架:

代码说明
1:在父类greet中定义了方法method1();method2(); method3(); 其中 method1();method3()为greet类的非虚函数。在greet类中实现。method2()为纯虚函数,需要在子类中实现。
class greet{
public:
greet() {
}
virtual ~greet(){
}
public:
virtual void method2() = 0;
private:
void method1();
void method3();
protect:
void greetProcess();
};
整个算法调用的接口在父类中定义和实现
void greet::greetProcess(){
method1();
method2();
method3();
}
派生类myGreet 继承 greet类,并且重写方法method2
class myGreet : public greet{
public:
myGreet() {
}
~myGreet(){
}
private:
void method2();
};
#endif
在源文件myMain.cpp 中定义基类指针指向派生类,并且调用基类中的算法流程接口
int main(){
greet *baseGreet = new myGreet;
baseGreet->greetProcess();
delete baseGreet;
return 0;
}
代码编译:在buildSh目录下面运行myBuild.sh
运行:buildSh目录下面执行myStart.sh
清理编译文件:buildSh目录下面执行myClean.sh
源码下载地址:设计模式之模板方法测试代码
一个经典的 C++ 源码示例涉及使用模板方法设计模式的场景是 GUI 框架的开发。在这样的框架中,通常会有一个基类定义了一些通用的行为和算法,而具体的子类可以根据需要来实现特定的功能或定制化。
#include <iostream>
// GUI 元素基类
class UIElement {
public:
// 模板方法:渲染
void render() {
// 绘制背景
drawBackground();
// 绘制内容
drawContent();
// 绘制边框
drawBorder();
}
protected:
// 子类必须实现的抽象方法:绘制内容
virtual void drawContent() = 0;
// 可选的钩子方法:绘制背景,默认实现为空
virtual void drawBackground() {}
// 可选的钩子方法:绘制边框,默认实现为空
virtual void drawBorder() {}
};
// 具体的按钮类
class Button : public UIElement {
protected:
// 实现绘制内容的具体算法
void drawContent() override {
std::cout << "Button: Drawing content." << std::endl;
}
// 实现绘制背景的具体算法
void drawBackground() override {
std::cout << "Button: Drawing background." << std::endl;
}
// 实现绘制边框的具体算法
void drawBorder() override {
std::cout << "Button: Drawing border." << std::endl;
}
};
// 具体的文本框类
class TextBox : public UIElement {
protected:
// 实现绘制内容的具体算法
void drawContent() override {
std::cout << "TextBox: Drawing content." << std::endl;
}
// 实现绘制背景的具体算法
void drawBackground() override {
std::cout << "TextBox: Drawing background." << std::endl;
}
};
int main() {
// 创建一个按钮并渲染
Button button;
std::cout << "Rendering button:" << std::endl;
button.render();
std::cout << std::endl;
// 创建一个文本框并渲染
TextBox textBox;
std::cout << "Rendering text box:" << std::endl;
textBox.render();
return 0;
}
在这个示例中,UIElement 类定义了一个模板方法 render(),它包含了一个固定的渲染算法框架。具体的子类(如 Button 和 TextBox)通过实现抽象方法 drawContent() 来定制化自己的渲染内容,而可选的钩子方法 drawBackground() 和 drawBorder() 则允许子类根据需要选择性地覆盖默认行为。
通过使用模板方法设计模式,GUI 框架可以提供一个通用的渲染算法框架,并允许具体的子类在不同的情况下定制化自己的行为,从而实现了代码的灵活性和可扩展性。