设计模式(十)——模板方法模式
AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,
每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),
用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作
优点:
(1) 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
(2) 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行
为,它鼓励我们恰当使用继承来实现代码复用。
(3) 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特
(4) 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则
和开闭原则。
适用场景
(1)具有统一的操作步骤或操作过程;
(2) 具有不同的操作细节;
(3) 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各
不相同;
在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样
可以把各个具体的子类和操作步骤解耦合。
#include <iostream> using namespace std; class MakeDrink { public: MakeDrink(bool add):m_add(add){} // 通用接口 virtual void boil_water() { cout << "煮水" << endl; } // 冲泡,特殊接口 virtual void brew() = 0; // 通用接口 virtual void pour_in_cup() { cout << "倒入杯中" << endl; } // 添加佐料 virtual void add_condiment() = 0; // 钩子函数,子类可以通过修改它来控制既有流程得到改变 virtual bool customer_want_condiment() { return m_add; } void make() { boil_water(); brew(); pour_in_cup(); if ( customer_want_condiment() ) add_condiment(); } protected: bool m_add; }; class Coffee :public MakeDrink { public: Coffee(bool add):MakeDrink(add) {} virtual void brew() { cout << "咖啡" << endl; } virtual void add_condiment() { cout << "加糖" << endl; } }; class Tea :public MakeDrink { public: Tea(bool add):MakeDrink(add) {} virtual void brew() { cout << "茶" << endl; } virtual void add_condiment() { cout << "柠檬" << endl; } }; int main() { MakeDrink* coffee = new Coffee(true); coffee->make(); cout << "------------------" << endl; MakeDrink* tea = new Tea(false); tea->make(); system("pause"); return 0; }