策略模式(Strategy Pattern)在 C++ 中的实现
1. 策略模式定义
策略模式定义了一系列算法(策略类),将每个算法封装起来,使它们可以相互替换,达到灵活使用不同策略的目的。在策略模式中,算法被封装成一系列具体策略类,作为抽象策略类的子类。根据实际需要选择合适的策略类来使用。
2. 策略模式角色
- Context(环境类) :持有对抽象策略类的引用,这里指
Fighter
类。 - Strategy(抽象策略类) :定义所支持的算法的公共接口,是所有具体策略类的父类,这里指
ItemStrategy
类。 - ConcreteStrategy(具体策略类) :实现抽象策略类中声明的接口的子类,这里包括
ItemStrategy_Bxd
、ItemStrategy_Dhd
和ItemStrategy_Shd
。
3. 策略模式优缺点
优点
- 以扩展的方式支持未来的变化,符合开闭原则。
- 能有效替代大量不稳定的
if
或switch
条件分支。 - 提高算法的复用性。
- 改变环境对象的行为通过设置不同的策略类来实现。
缺点
- 可能导致引入许多新策略类。
- 使用策略时,调用者必须了解所有策略的功能,并选择合适的策略。
4. C++ 示例代码
以下是使用策略模式的 C++ 示例代码:
cpp
#include <iostream>
#include <memory>
using namespace std;
// 前向声明
class Fighter;
// 策略基类
class ItemStrategy {
public:
virtual void UseItem(Fighter* fighter) = 0; // 使用道具的纯虚函数
virtual ~ItemStrategy() {} // 虚析构函数
};
// 战士类
class Fighter {
public:
Fighter(int life, int magic, int attack)
: life(life), magic(magic), attack(attack), itemStrategy(nullptr) {}
void SetItemStrategy(ItemStrategy* strategy) {
itemStrategy = strategy; // 设置当前的道具策略
}
void UseItem() {
if (itemStrategy) {
itemStrategy->UseItem(this); // 使用当前的道具策略
}
}
int GetLife() const {
return life; // 获取生命值
}
void SetLife(int life) {
this->life = life; // 设置新的生命值
}
virtual ~Fighter() {} // 虚析构函数
protected:
int life; // 生命值
int magic; // 魔法值
int attack; // 攻击力
ItemStrategy* itemStrategy; // 当前使用的道具策略
};
// 补血丹策略类
class ItemStrategy_Bxd : public ItemStrategy {
public:
virtual void UseItem(Fighter* fighter) override {
fighter->SetLife(fighter->GetLife() + 200); // 补充生命值
}
};
// 大还丹策略类
class ItemStrategy_Dhd : public ItemStrategy {
public:
virtual void UseItem(Fighter* fighter) override {
fighter->SetLife(fighter->GetLife() + 300); // 补充生命值
}
};
// 守护丹策略类
class ItemStrategy_Shd : public ItemStrategy {
public:
virtual void UseItem(Fighter* fighter) override {
fighter->SetLife(fighter->GetLife() + 500); // 补充生命值
}
};
// 战士类
class F_Warrior : public Fighter {
public:
F_Warrior(int life, int magic, int attack) : Fighter(life, magic, attack) {}
};
// 法师类
class F_Mage : public Fighter {
public:
F_Mage(int life, int magic, int attack) : Fighter(life, magic, attack) {}
};
int main() {
// 创建一个战士角色
Fighter* role_var = new F_Warrior(1000, 0, 200);
cout << "初始生命值: " << role_var->GetLife() << endl;
// 使用补血丹策略
ItemStrategy* strategy = new ItemStrategy_Bxd();
role_var->SetItemStrategy(strategy);
role_var->UseItem();
// 使用大还丹策略
ItemStrategy* strategy2 = new ItemStrategy_Dhd();
role_var->SetItemStrategy(strategy2);
role_var->UseItem();
// 输出最终生命值
cout << "使用补血丹和大还丹后的生命值: " << role_var->GetLife() << endl;
// 释放内存
delete strategy; // 释放补血丹策略对象
delete strategy2; // 释放大还丹策略对象
delete role_var; // 释放角色对象
return 0;
}
5. 总结
策略模式是一种灵活的设计模式,可以帮助我们在不改变环境类的情况下,轻松地替换和添加新的策略。通过合理运用策略模式,可以有效地提升代码的可维护性和可扩展性。