0. 简介

作为行为模式的倒数第三章,策略模式在我们编写算法时是非常重要的,它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换

1. 策略模式示意图

我们可以清晰的从图中看出策略模式本质上的操作就是定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在我们对一个类的行为或其算法改变时,是不会增加Context的内容的。
在这里插入图片描述
上下文(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。

抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。

具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。

2. 示例代码

策略模式是一个比较容易理解和使用的设计模式, 策略模式是对算法的封装 , 它把算法的责任和算法本身分割开 , 委派给不同的对象管理 。策略模式通常 把一个系列的算法封装到一系列的策略类里面 ,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。

#include <iostream>
//飞行行为,用抽象类表示
classFlyBehavior{
public:
   virtual ~FlyBehavior(){};
   virtual void fly() =0;
};
//叫声行为,用抽象类表示
classQuackBehavior{
public:
   virtual ~QuackBehavior(){};
   virtual void quack()= 0;
};
//鸭子基类,有display,performFly, performQuack,swim等方法。
classDuck{
public:
   Duck(FlyBehavior*p_FlyBehavior,QuackBehavior* p_QuackBehavior)
   {
      pFlyBehavior= p_FlyBehavior;
      pQuackBehavior= p_QuackBehavior;

   }
   virtual ~Duck(){};
   virtual voiddisplay(){};
   void performFly()
   {
      pFlyBehavior->fly();
   }
   void performQuack()
   {
      pQuackBehavior->quack();
   }
   void swim()
   {
      std::cout<<("All ducks float, even decoys!")<< std::endl;
   }
private:
   FlyBehavior*pFlyBehavior;
   QuackBehavior*pQuackBehavior;
};
//实现飞行行为的方法类
classFlyWithWings : public FlyBehavior{
public:
   void fly(){
   std::cout<< ("I'm flying!!")<<std::endl;
   }
};

classFlyNoWay : public FlyBehavior{
public:
   void fly(){
   std::cout<< ("I can't fly")<<std::endl;
   }
};
//实现叫声行为的类
classQuack : public QuackBehavior{
public:
   void quack(){
   std::cout<< ("Quack") <<std::endl;
   }
};

classMuteQuack : public QuackBehavior{
public:
   void quack(){
   std::cout<< ("<< Slience >>")<< std::endl;
   }
};

classSqueak : public QuackBehavior{
public:
   void quack(){
   std::cout<< "Squeak"<<std::endl;
   }
};
//绿头鸭类
classMallardDuck : public Duck{
public:
   MallardDuck(FlyBehavior*fly_behavior = new FlyWithWings(),
      QuackBehavior*quack_behavior = new Quack())
      :Duck(fly_behavior,quack_behavior){}

   void display()
   {
      std::cout<< "I'm a real Mallard duck"<< std::endl;
   }
};

intmain()
{
   Duck*mallard = new MallardDuck();
   mallard->performFly();
   mallard->performQuack();
   return 0;
}

3. 策略模式的比较与优缺点

策略模式和其它许多设计模式比较起来是非常类似的。策略模式和状态模式最大的区别就是策略模式只是的条件选择只执行一次。

策略模式的想法和工厂模式组成和代码结构类似,但是这两者存在逻辑上的区别,这就需要我们明确我们的目标是什么了:

工厂模式是创建型模式 ,它关注对象创建,提供创建对象的接口. 让对象的创建与具体的使用客户无关。这里会用一个工厂类来统一管理调用。

策略模式是对象行为型模式 ,它关注行为和算法的封装 。它定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。使得算法可独立于使用它的客户而变化。这个时候可以通过直接调用基类的方式完成赋值。

在这里插入图片描述

4. 参考链接

https://refactoringguru.cn/design-patterns/strategy

https://blog.csdn.net/hguisu/article/details/7558249

https://blog.csdn.net/walkerkalr/article/details/28422609