模板方法模式定义
定义一个操作中算法的框架,将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
所谓将一些步骤延迟到子类中实现的意思就是子类继承实现父类中的虚函数。
从封装变化的角度去看,模板方法模式用于组件协作
方面。
简单案例
在日常生活中,冲咖啡和冲茶叶的基本步骤是比较类似。
冲咖啡大致步骤:
1、煮水 2、冲泡咖啡 3、倒入杯中 4、加糖和牛奶
冲茶大致步骤:
1、煮水 2、冲泡茶叶 3、倒入杯中 4、加柠檬
class DrinkMaker
{
protected:
virtual void Boil() = 0; //煮水
virtual void Brew() = 0; //冲泡
virtual void Pour() = 0; //倒入
virtual void Add() = 0; //添加佐料
public:
void Make()
{
Boil();
Brew();
Pour();
Add();
}
};
class GeneralCoffee : public DrinkMaker{
protected:
void Boil()
{
cout << "煮自来水" << endl;
}
void Brew()
{
cout << "冲泡咖啡" << endl;
}
void Pour()
{
cout << "倒入瓷杯" << endl;
}
void Add()
{
cout << "添加牛奶和糖" << endl;
}
};
class ZhandsanCoffee : public DrinkMaker{
protected:
void Boil()
{
cout << "煮自来水" << endl;
}
void Brew()
{
cout << "冲泡咖啡" << endl;
}
void Pour()
{
cout << "倒入瓷杯" << endl;
}
void Add(){
} //张三喜欢喝斋啡,什么都不加
};
class GeneralTea : public DrinkMaker
{
protected:
void Boil()
{
cout << "煮山泉水" << endl;
}
void Brew()
{
cout << "冲泡茶叶" << endl;
}
void Pour()
{
cout << "倒入保温杯中" << endl;
}
void Add(){
} //一般人喝茶都不会添加什么佐料
};
class ProgrammerTea : public DrinkMaker
{
protected:
void Boil()
{
cout << "煮山泉水" << endl;
}
void Brew()
{
cout << "冲泡茶叶" << endl;
}
void Pour()
{
cout << "倒入保温杯中" << endl;
}
void Add()
{
cout << "添加枸杞" << endl; //程序员的茶,保温杯里泡狗起
}
};
int main()
{
GeneralCoffee *gCoffee = new GeneralCoffee;
gCoffee->Make();
cout << endl;
ZhandsanCoffee *zsCoffee = new ZhandsanCoffee;
zsCoffee->Make();
cout << endl;
GeneralTea *gTea = new GeneralTea;
gTea->Make();
cout << endl;
ProgrammerTea *pTea = new ProgrammerTea;
pTea->Make();
delete gCoffee;
delete zsCoffee;
delete gTea;
delete pTea;
return 0;
}
从上面例子中可以总结出模板方法模式的优点
模板方法模式优点
1、父类中形式化定义一个算法,由子类处理细节,在子类中实现详细处理的算法并不会改父类中定义的算法的步骤执行次序
2、使用代码可以服用,在类库设计中很重要,可以提取出类库中的公共行为放在父类中,通过子类来实现不同的行为,可以恰当使用继承来是代码复用
3、可实现一种反向控制结构,通过子类覆盖父类的虚函数来决定某一步骤是否需要执行,比如 子类实现父类的重写实现父类虚函数,但是什么都不做,那这一个步骤就是不需要执行的。
4、模板方法模式很好体现了面向对象的特点,不同的子类可以提供不同的方法覆盖父类中的虚函数,使得更换和增加子类的很方便, 符合单一职责和开关原则。