设计模式 - 模板方法模式(Template Method Pattern)
flyfish
模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,而将某些步骤的实现延迟到子类中。通过这种方式,模板方法模式允许子类在不改变算法结构的情况下,重新定义算法中的某些步骤。
C++ 里面也有模板, C++ 模板(Templates)是一种编程语言特性,主要用于实现通用编程,允许在编译时生成适用于不同数据类型的代码。这里的模板方法模式是一个设计模式,强调的是定义算法的骨架,允许子类改变算法的某些步骤。
模板方法模式的核心思想
-
算法骨架 :在一个抽象类中定义一个算法的骨架。这个骨架是一个具体的方法,称为模板方法。
-
步骤实现 :算法的某些步骤由抽象方法定义,这些方法需要在子类中实现。
-
不变的部分和可变的部分 :模板方法模式将算法中不变的部分放在抽象类中,而将可变的部分留给子类实现。
模板方法模式的结构
-
AbstractClass(抽象类) :
包含一个或多个模板方法,定义了算法的骨架。
包含一些基本方法,其中可以有抽象方法和钩子方法。 -
ConcreteClass(具体类) :
继承自AbstractClass
,实现抽象类中的抽象方法,定义具体步骤。
简单示例,展示制作饮料的过程
#include <iostream>
// 抽象类,定义饮料制作的模板方法
class Beverage {
public:
// 模板方法,定义制作饮料的步骤
void prepareBeverage() {
boilWater();
brew();
pourInCup();
addCondiments();
}
// 基本方法:煮沸水
void boilWater() {
std::cout << "Boiling water" << std::endl;
}
// 基本方法:倒入杯中
void pourInCup() {
std::cout << "Pouring into cup" << std::endl;
}
// 抽象方法:冲泡饮料(由子类实现)
virtual void brew() = 0;
// 抽象方法:添加调料(由子类实现)
virtual void addCondiments() = 0;
};
// 具体类:咖啡
class Coffee : public Beverage {
protected:
void brew() override {
std::cout << "Brewing coffee" << std::endl;
}
void addCondiments() override {
std::cout << "Adding sugar and milk" << std::endl;
}
};
// 具体类:茶
class Tea : public Beverage {
protected:
void brew() override {
std::cout << "Steeping tea" << std::endl;
}
void addCondiments() override {
std::cout << "Adding lemon" << std::endl;
}
};
int main() {
Coffee coffee;
Tea tea;
std::cout << "Preparing coffee:" << std::endl;
coffee.prepareBeverage();
std::cout << "\nPreparing tea:" << std::endl;
tea.prepareBeverage();
return 0;
}
代码示例 定义一个抽象基类 GameAI
来定义算法的骨架,并由具体子类如 OrcsAI
和 MonstersAI
实现具体的步骤使用 C++ 的抽象类和继承来实现这一模式
-
抽象基类
GameAI
:
包含一个模板方法turn()
,定义了算法的框架。
提供一个具体实现的方法collectResources()
。
定义了一些纯虚函数(抽象方法),如buildStructures()
、buildUnits()
、sendScouts()
、sendWarriors()
,由子类实现。 -
具体类
OrcsAI
和MonstersAI
:
继承自GameAI
,并实现了所有抽象方法。
OrcsAI
实现了具体的建造和攻击策略。
MonstersAI
覆盖了collectResources()
方法,并实现了它们自己的攻击逻辑。
#include <iostream>
#include <vector>
#include <string>
// 抽象基类:GameAI
class GameAI {
public:
// 模板方法定义算法的框架
void turn() {
collectResources();
buildStructures();
buildUnits();
attack();
}
// 某些步骤可以在基类中实现
virtual void collectResources() {
for (auto& structure : builtStructures) {
structure.collect();
}
}
// 抽象方法,由子类实现
virtual void buildStructures() = 0;
virtual void buildUnits() = 0;
// 一个类可以包含多个模板方法
void attack() {
auto enemy = closestEnemy();
if (enemy.empty()) {
sendScouts("map center");
} else {
sendWarriors(enemy);
}
}
// 抽象方法,由子类实现
virtual void sendScouts(const std::string& position) = 0;
virtual void sendWarriors(const std::string& position) = 0;
protected:
// 模拟已建造结构的集合
struct Structure {
void collect() {
std::cout << "Collecting resources from structure.\n";
}
};
std::vector<Structure> builtStructures;
// 模拟查找最近的敌人
std::string closestEnemy() {
return "enemy position";
}
};
// 具体类:OrcsAI
class OrcsAI : public GameAI {
public:
void buildStructures() override {
std::cout << "Orcs are building structures.\n";
}
void buildUnits() override {
std::cout << "Orcs are building units.\n";
}
void sendScouts(const std::string& position) override {
std::cout << "Orcs sending scouts to " << position << ".\n";
}
void sendWarriors(const std::string& position) override {
std::cout << "Orcs sending warriors to " << position << ".\n";
}
};
// 具体类:MonstersAI
class MonstersAI : public GameAI {
public:
void collectResources() override {
std::cout << "Monsters do not collect resources.\n";
}
void buildStructures() override {
std::cout << "Monsters do not build structures.\n";
}
void buildUnits() override {
std::cout << "Monsters do not build units.\n";
}
void sendScouts(const std::string& position) override {
std::cout << "Monsters sending scouts to " << position << ".\n";
}
void sendWarriors(const std::string& position) override {
std::cout << "Monsters sending warriors to " << position << ".\n";
}
};
int main() {
OrcsAI orcsAI;
MonstersAI monstersAI;
std::cout << "Orcs AI turn:\n";
orcsAI.turn();
std::cout << "\nMonsters AI turn:\n";
monstersAI.turn();
return 0;
}