描述
策略模式(Strategy Pattern)是一种行为型设计模式,它允许在运行时根据不同的情况选择算法的行为。该模式将算法的定义封装成一组易于切换和替换的类,使得算法可以独立于其使用者进行变化。
原理
策略模式通过将具体的算法封装在独立的策略类中,使得每个策略类都可以互相替换,而不会影响到客户端的代码。客户端通过持有某个策略类的引用,可以在运行时选择不同的策略以达到不同的行为。
类图
示例
假设有一个游戏角色类,角色需要根据不同的武器选择不同的攻方式。
首先,定义一个策略接口(Strategy),包含一个攻击方法(attack);
其次,创建几个具体的策略类,如剑士策略(SwordsmanStrategy)、弓箭手策略(ArcherStrategy)等,每个策略类实现攻击方法;
最后,在角色类(Character)中持有一个策略对象,并在需要攻击时调用策略对象的攻击方法。
C++示例代码如下:
// 策略接口
class Strategy {
public:
virtual void attack() = 0;
};
// 剑士策略
class SwordsmanStrategy : public Strategy {
public:
void attack() override{
cout << "使用剑进行攻击!" << endl;
}
};
// 弓箭手策略
class ArcherStrategy : public Strategy {
public:
void attack() override {
cout << "使用弓箭进行攻击!" << endl;
}
};
// 角色类
class Character {
private:
Strategy* strategy;
public:
Character(Strategy* strategy) : strategy(strategy) {}
void setStrategy(Strategy* newStrategy) {
strategy = newStrategy;
}
void attack() {
strategy->attack();
}
};
// 使用示例
int main() {
Strategy* swordsmanStrategy = new SwordsmanStrategy();
Strategy* archerStrategy = new ArcherStrategy();
Character character(swordsmanStrategy);
character.attack(); // 输出: 使用剑进行攻击!
character.setStrategy(archerStrategy);
character.attack(); // 输出: 使用弓箭进行攻!
delete swordsmanStrategy;
swordsmanStrategy = 0;
delete archerStrategy;
archerStrategy = 0;
return 0;
}
解释
在上述示例中,策略接口(Strategy)定义了攻击方法,然后创建了两个具体的策略类:剑士策略(SwordsmanStrategy和弓箭手策略(ArcherStrategy),它们分别实现了攻击方法。角色类(Character)持有一个策略对象,并在需要攻击时调用策略对象的攻击方法。
结论
策略模式通过使用接口或抽象类来定义一组算法,将其封装在不同的策略类中以实现算法的独立变化。这种设计模式可以提高代码的扩展性和可维护性。
应用场景
策略模式用于以下情况:
- 当一个系统需要在多个算法中自由切换时;
- 当一个类的行为可以在运行时根据不同条件选择不同的算法时;
- 当需要通过扩展来增加新的算法,而不影响到使用算法的客户端代码时。
策略模式可以应用于各种场景,如支付方式选择、排序算法选择等。它将算法的选择与具体的业务逻辑分离,使得系统更加灵活和易于维护。