第一次学习策略模式参考的是head first那本书,里面第一章就介绍了策略模式,所以,策略模式是我接触的第一个设计模式。
文中用鸭子的扩展作为实例,讲了游戏中需要扩展鸭子类,发现有些行为方法是鸭子类共有的,可以直接(将其函数实现)放在基类中,有些行为方法是某些鸭子独有的,直接以函数实现的方式放在基类中的话,那所有继承基类鸭的派生鸭都会继承这个函数方法(包括没有实现这个方法的派生鸭),这是没有必要的,而且你还需要去覆盖实现,并且无法实现代码复用。
最后问题的解决办法就是策略模式——方法是将不同子类中特有的行为从基类中提取出来,抽象为一个行为基类,然后去根据该行为的不同实现方式去派生子类(比如飞行行为,先抽象一个飞行基类,然后派生实现其各种子类:不会飞行,用翅膀飞行,喷气式飞行等等),最后在鸭子基类中加入该行为基类的指针变量,并通过该基类指针实现该行为的函数方法。
说起来比较绕,对于程序员来说,还是代码比较好理解(🤭)。所以这里,咱们上代码。
#include<iostream>
//行为,抽象出来
class FlyBehavior
{
public:
virtual void makeFly() = 0;
virtual ~FlyBehavior() {}; //虚析构,避免析构的时候漏了析构子类,虽然子类没有啥需要析构的
};
class FlyWithWings:public FlyBehavior
{
public:
void makeFly() { std::cout << "我用翅膀飞,飞的贼快,就是有点累" << std::endl; }
};
class FlyByJet :public FlyBehavior
{
public:
void makeFly() { std::cout << "我喷气飞,飞的贼快,而且还不累" << std::endl; }
};
class FlyUseSleep :public FlyBehavior
{
public:
void makeFly() { std::cout << "我做梦的时候才能飞,不作梦根本飞不起来" << std::endl; }
};
//鸭子 ,基类
class Duck
{
protected:
FlyBehavior *m_fly;
public:
virtual void swim() { std::cout << "作为一只鸭子,我会游泳" << std::endl; }
virtual void display(){ std::cout << "作为一只鸭子,我的长相肯定是非常帅气的" << std::endl; }
virtual void fly() { m_fly->makeFly(); }
public:
Duck(FlyBehavior *fly_behavior):m_fly(fly_behavior){};
virtual ~Duck()
{
if (m_fly != NULL) delete m_fly;
}
};
class MallardDuck : public Duck
{
public:
MallardDuck(FlyBehavior *fly_behavior):Duck(fly_behavior){};
//可以重写swim和display
};
class RubberDuck : public Duck
{
public:
RubberDuck(FlyBehavior *fly_behavior) :Duck(fly_behavior) {};
//可以重写swim和display
};
//主函数
void main()
{
Duck *ya1 = new MallardDuck(new FlyWithWings());
Duck *ya2= new RubberDuck(new FlyUseSleep());
ya1->fly();
ya2->fly();
delete ya1;
delete ya2;
system("pause");
return;
}