23种设计模式(C++)之 模板方法(Template Method)模式
意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性
- 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
- 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
- 控制子类扩展。模板方法只在特定点调用“hook”操作,这样就只允许在这些点进行扩展。
场景
一般针对多个子类有相同的方法或逻辑,比如操作电子设备,逻辑都是接线->上电->开机->关机;或者比赛,流程也都差不多,都是准备->开始->结束。这类场景都可以用模板方法将这些流程抽象出来。
角色
- AbstractClass
- 定义抽象的原语操作,具体的子类将重新定义它们以实现一个算法的各步骤。
- 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。
- ConcreteClass
- 实现原语操作以完成算法中于特定子类相关的步骤。
实例
- 创建模板接口
class ElectricDevice
{
public:
virtual void prepare() = 0;
virtual void powerOn() = 0;
virtual void shutDown() = 0;
void operateDevice()
{
//Prepare device
this->prepare();
//Power on
this->powerOn();
//Shut on
this->shutDown();
}
};
- 创建具体的电子设备
class Laptop :public ElectricDevice
{
public:
void prepare()
{
cout << "The cable of laptop is plugged in." << endl;
}
void powerOn()
{
cout << "Power on laptop." << endl;
}
void shutDown()
{
cout << "Shut the laptop down." << endl;
}
};
class Refrigerator :public ElectricDevice
{
public:
void prepare()
{
cout << "The cable of refrigerator is plugged in." << endl;
}
void powerOn()
{
cout << "Power on refrigerator." << endl;
}
void shutDown()
{
cout << "Shut the refrigerator down." << endl;
}
};
- Client
int main()
{
Laptop* laptop = new Laptop();
laptop->operateDevice();
Refrigerator* refrigerator = new Refrigerator();
refrigerator->operateDevice();
}
- Result
The cable of laptop is plugged in.
Power on laptop.
Shut the laptop down.
The cable of refrigerator is plugged in.
Power on refrigerator.
Shut the refrigerator down.