一、状态设计模式概念
策略模式(Strategy) 是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
适用场景
- 当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时, 可使用策略模式。
- 当你有许多仅在执行某些行为时略有不同的相似类时, 可使用策略模式。
- 如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
- 当类中使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。
状态设计模式的结构:
- 上下文 (Context) 维护指向具体策略的引用, 且仅通过策略接口与该对象进行交流。
- 策略 (Strategy) 接口是所有具体策略的通用接口, 它声明了一个上下文用于执行策略的方法。
- 具体策略 (Concrete Strategies) 实现了上下文所用算法的各种不同变体。
- 当上下文需要运行算法时, 它会在其已连接的策略对象上调用执行方法。 上下文不清楚其所涉及的策略类型与算法的执行方式。
- 客户端 (Client) 会创建一个特定策略对象并将其传递给上下文。 上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。
代码如下:
问题:做一款打斗游戏,玩家使用的英雄使用不同的武器将会产生不同的损伤效果。
解决方案:定义一些列的算法,把他们一个个封装起来,并且使它们可以相互替换。本模式使得算法可以独立于使用它的客户而变化。
#include <iostream>
#include <string>
class Weapon
{
public:virtual std::string fightAlgorithm() const = 0;
};class Nife: public Weapon
{
public:std::string fightAlgorithm() const override{return "nife";}
};class Axe : public Weapon
{
public:std::string fightAlgorithm() const override{return "Axe";}
};//context
class Hero
{
private:Weapon* m_weapon;
public:Hero(Weapon* weapon=nullptr) : m_weapon(weapon){}void setWeapon(Weapon* weapon){m_weapon = weapon;}void fight(){std::cout << m_weapon->fightAlgorithm() << std::endl;}
};int main()
{std::cout<<"客户端:nife攻击"<<std::endl;Nife nife;Hero hero1(&nife);hero1.fight();std::cout<<"客户端:Axe攻击"<<std::endl;Axe axe;hero1.setWeapon(&axe);hero1.fight();return 0;
}
二、与其他模式的关系
- 桥接模式 (opens new window)、 状态模式 (opens new window)和策略模式 (opens new window)(在某种程度上包括适配器模式 (opens new window)) 模式的接口非常相似。 实际上, 它们都基于组合模式 (opens new window)——即将工作委派给其他对象, 不过也各自解决了不同的问题。 模式并不只是以特定方式组织代码的配方, 你还可以使用它们来和其他开发者讨论模式所解决的问题。
- 状态 (opens new window)可被视为策略 (opens new window)的扩展。 两者都基于组合机制: 它们都通过将部分工作委派给 “帮手” 对象来改变其在不同情景下的行为。 策略使得这些对象相互之间完全独立, 它们不知道其他对象的存在。 但状态模式没有限制具体状态之间的依赖, 且允许它们自行改变在不同情景下的状态。