//下面是一个使用模板方法设计模式的代码示例:
//```cpp
//#include
// 抽象基类
#include
class CaffeineBeverage {
public:
virtual ~CaffeineBeverage() {};
// 模板方法,定义了基本算法骨架
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
// 这两个方法在子类中实现
virtual void brew() = 0;
virtual void addCondiments() = 0;
// 这两个方法是基类中的具体实现,不会被子类重写
void boilWater() {
std::cout << "Boiling water." << std::endl;
}
void pourInCup() {
std::cout << "Pouring into cup." << std::endl;
}
// 钩子方法,由子类选择性地决定是否执行
virtual bool customerWantsCondiments() {
return true;
}
};
// 具体类
class Tea : public CaffeineBeverage {
public:
void brew() override {
std::cout << "Steeping the tea." << std::endl;
}
void addCondiments() override {
std::cout << "Adding lemon." << std::endl;
}
};
class Coffee : public CaffeineBeverage {
public:
void brew() override {
std::cout << "Dripping coffee through filter." << std::endl;
}
void addCondiments() override {
std::cout << "Adding sugar and milk." << std::endl;
}
bool customerWantsCondiments() override {
char answer;
std::cout << "Do you want to add sugar and milk? (y/n): ";
std::cin >> answer;
return answer == 'y';
}
};
int main() {
Tea tea;
Coffee coffee;
std::cout << "Making tea..." << std::endl;
tea.prepareRecipe();
std::cout << "Making coffee..." << std::endl;
coffee.prepareRecipe();
return 0;
}
//```
//
//在上面的代码中,`CaffeineBeverage`是一个抽象基类,其中定义了一个模板方法`prepareRecipe()`
// 和三个基本操作方法`boilWater()`、`brew()`、`pourInCup()`,分别对应制作饮料的基本步骤,
// 其中`brew()`和`addCondiments()`方法需要在具体子类中实现,由于这两个方法在制作不同类型的饮料时有所不同,
// 所以需要在子类中进行实现。
//
//在`prepareRecipe()`方法中,将基本操作方法按照预期的顺序组织起来形成了模板方法,
// 而钩子方法`customerWantsCondiments()`将决定是否执行添加调味品这一步骤,
// 在`Coffee`类中,使用了钩子方法来获取用户选择是否添加调味品的意愿,而`Tea`类则始终要求添加柠檬,因此没有使用钩子方法。
//
//通过运行上面的代码,我们可以得到以下输出:
//
//```
//Making tea...
//Boiling water.
//Steeping the tea.
//Pouring into cup.
//Adding lemon.
//Making coffee...
//Boiling water.
//Dripping coffee through filter.
//Pouring into cup.
//Do you want to add sugarand milk ? (y / n) : y
//Adding sugar and milk.
//```
//
//从上面的输出可以看出,在方法调用过程中,按照模板方法中定义的顺序执行了基本操作方法,
//在`coffee`类中使用钩子方法获取了用户选择是否添加调味品的意愿,在`tea`类中则直接添加了柠檬。