版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shineboyxxb/article/details/52277670
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。这个模式主要用来创建一个算法的模板(即模板方法),模板中包括了实现这个算法的几个固定步骤,这些步骤中主要可以分为三类:第一类是所有子类都共用的步骤,这类步骤直接在基类中定义为非虚函数;第二类是所有子类必须根据自身情况自己提供实现的步骤,这类步骤在基类中被定义为纯虚函数;第三类是子类可以根据需要决定是否重新实现的步骤,这类步骤在基类中被定义为普通虚函数。
模板方法的类图如下:
下面以一个例子来说明模板方法的使用:
定义了一个咖啡因饮料制作的模板方法,子类coffee和tea继承自该类,并提供模板方法用到的方法的具体实现。具体程序如下:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <memory>
using namespace std;
//抽象基类
class CaffeineBeverageWithHook {
public:
//模板方法,包含了某个算法的几个固定步骤
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
virtual void brew()=0; //必须由子类实现的步骤
virtual void addCondiments()=0; //必须由子类实现的步骤
//不需要子类实现的步骤
void boilWater() {
cout<<"Boiling water"<<endl;
}
//不需要子类实现的步骤
void pourInCup() {
cout<<"Pouring into cup"<<endl;
}
//子类可以根据需要决定是否实现的方法(也称为钩子方法hook)
virtual bool customerWantsCondiments() {
return true;
}
};
//具体的子类实现
class CoffeeWithHook:public CaffeineBeverageWithHook {
public :
void brew() {
cout<<"Dripping Coffee through filter"<<endl;
}
void addCondiments() {
cout<<"Adding Sugar and Milk"<<endl;
}
bool customerWantsCondiments() {
string answer = getUserInput();
if (tolower(answer[0])=='y') {
return true;
} else {
return false;
}
}
private :
string getUserInput() {
string answer = "";
cout<<"Would you like milk and sugar with your coffee (y/n)? "<<endl;
cin>>answer;
return answer;
}
};
//具体的子类实现
class TeaWithHook:public CaffeineBeverageWithHook {
public:
void brew() {
cout<<"Steeping the tea"<<endl;
}
void addCondiments() {
cout<<"Adding Lemon"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
shared_ptr<CoffeeWithHook> coffeeHook = shared_ptr<CoffeeWithHook>(new CoffeeWithHook());
cout<<"Making coffee..."<<endl;
coffeeHook->prepareRecipe();
cout<<endl<<endl;
shared_ptr<TeaWithHook> teaHook=shared_ptr<TeaWithHook>(new TeaWithHook());
cout<<"Making tea..."<<endl;
teaHook->prepareRecipe();
return 0;
}
程序执行结果如下: