模板方法设计模式适用于以下情况:
• 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现;
• 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复;
• 控制子类扩展,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展;
下面是一个模板方法模式的示例程序:
cpp
#include <iostream>
#include <string>
#include <memory>
// =================================================================
// Step 1: THE ABSTRACT CLASS WITH THE TEMPLATE METHOD
// =================================================================
class GameCharacter {
public:
virtual ~GameCharacter() = default;
// THE TEMPLATE METHOD
// This defines the strict, unchangeable skeleton/sequence of a turn.
// Notice it is NOT virtual. Subclasses cannot change the step order.
void takeTurn() {
std::cout << "\n--- Starting Character Turn Sequence ---\n";
findTarget();
attack();
endTurn(); // A fixed step shared by all characters
std::cout << "--- Turn Completed Safely ---\n";
}
protected:
// Step 1: Subclasses must implement their own custom targeting logic
virtual void findTarget() = 0;
// Step 2: Subclasses must implement their own unique combat logic
virtual void attack() = 0;
// Step 3: A default implementation shared by all characters.
// Subclasses can optionally override this if they want to, but don't have to.
virtual void endTurn() {
std::cout << "[Default System] Regenerating +10 Mana/Stamina points.\n";
}
};
// =================================================================
// Step 2: CONCRETE SUBCLASSES (Customizing specific steps)
// =================================================================
// Character Type A: An Orc warrior
class Orc : public GameCharacter {
protected:
void findTarget() override {
std::cout << "[Orc Engine] Scanning for the closest enemy standing nearby.\n";
}
void attack() override {
std::cout << "[Orc Engine] Smashing target violently with a heavy iron axe!\n";
}
};
// Character Type B: A Magic Mage wizard
class Mage : public GameCharacter {
protected:
void findTarget() override {
std::cout << "[Mage Engine] Locating the enemy with the lowest total health points.\n";
}
void attack() override {
std::cout << "[Mage Engine] Casting a brilliant fireball spell from a distance!\n";
}
// Overriding the default optional hook step to add unique rules
void endTurn() override {
GameCharacter::endTurn(); // Call the base behavior first
std::cout << "[Mage Bonus] Teleporting 5 meters backward into a safe zone.\n";
}
};
// =================================================================
// Step 3: CLIENT CODE
// =================================================================
int main() {
std::cout << "=== Game Battle Round Starting ===\n";
// 1. Create our custom polymorphic game characters
std::unique_ptr<GameCharacter> player1 = std::make_unique<Orc>();
std::unique_ptr<GameCharacter> player2 = std::make_unique<Mage>();
// 2. Execute their turns.
// They run the exact same structural template sequence but execute custom code.
std::cout << "\n>>> Orc Player Turn:";
player1->takeTurn();
std::cout << "\n>>> Mage Player Turn:";
player2->takeTurn();
return 0;
}
程序运行结果如下:
shell
$ g++ -o main main.cpp
$ ./main
=== Game Battle Round Starting ===
>>> Orc Player Turn:
--- Starting Character Turn Sequence ---
[Orc Engine] Scanning for the closest enemy standing nearby.
[Orc Engine] Smashing target violently with a heavy iron axe!
[Default System] Regenerating +10 Mana/Stamina points.
--- Turn Completed Safely ---
>>> Mage Player Turn:
--- Starting Character Turn Sequence ---
[Mage Engine] Locating the enemy with the lowest total health points.
[Mage Engine] Casting a brilliant fireball spell from a distance!
[Default System] Regenerating +10 Mana/Stamina points.
[Mage Bonus] Teleporting 5 meters backward into a safe zone.
--- Turn Completed Safely ---