c++之设计模式:策略模式

模式定义        

策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

模式结构

 

  举例:

        游泳池中有不同种类的鸭子,有绿头鸭,红头鸭,橡皮鸭,木头鸭等。不同鸭子的特征或行为不同。绿头鸭(MallardDuck)可以叫声是“quack”,会飞;橡皮鸭叫声是“queak”,不会飞;木头鸭不会叫,也不会飞。利用面向对象原理来设计来泳池中的各种鸭。要求:1.可扩展性好,当有新鸭加入时或鸭的行为有变动时,不用大量改动代码;2.复用性强。

 设计UML图


        其中,Duck为一个基类,MallardDuck,RedheadDuck, RubberDuck, DecoyDuck继承自Duck。

FlyBehavior, QuackBehavior为鸭子的飞行和叫声行为,在java中可用接口表示,在C++中用抽象类表示。FlyWithWings等方法用来实现鸭子的行为。

#include <iostream>
using namespace std;
//飞行行为,用抽象类表示
class FlyBehavior{
public:
	virtual ~FlyBehavior(){};
	virtual void fly() = 0;
};

//实现飞行行为的方法类
class FlyWithWings : public FlyBehavior{
public:
	void fly(){
		std::cout << ("I'm flying!!") << std::endl;
	}
};

class FlyNoWay : public FlyBehavior{
public:
	void fly(){
		std::cout << ("I can't fly") << std::endl;
	}
};

//叫声行为,用抽象类表示
class QuackBehavior{
public:
	virtual ~QuackBehavior(){};
	virtual void quack() = 0;
};

//实现叫声行为的类
class Quack : public QuackBehavior{
public:
	void quack(){
		std::cout << ("Quack") << std::endl;
	}
};

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

class Squeak : public QuackBehavior{
public:
	void quack(){
		std::cout << "Squeak" << std::endl;
	}
};
//鸭子基类,有display,performFly, performQuack,swim等方法。
class Duck{
public:
	Duck(FlyBehavior*p_FlyBehavior, QuackBehavior* p_QuackBehavior)
	{
		pFlyBehavior = p_FlyBehavior;
		pQuackBehavior = p_QuackBehavior;

	}
	virtual ~Duck(){};
	virtual void display(){};
	void performFly()
	{
		pFlyBehavior->fly();
	}
	void performQuack()
	{
		pQuackBehavior->quack();
	}
	void swim()
	{
		std::cout << ("All ducks float, even decoys!") << std::endl;
	}
private:
	FlyBehavior* pFlyBehavior;
	QuackBehavior* pQuackBehavior;
};
//绿头鸭类
class MallardDuck : public Duck{
public:      //使用子类的对象初始化父类对象
	MallardDuck(FlyBehavior*p_FlyBehavior, QuackBehavior* p_QuackBehavior) :Duck(p_FlyBehavior, p_QuackBehavior){}

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

int main()
{
	FlyBehavior* pflybehavior = new FlyWithWings();
	QuackBehavior* pQuackbehavior = new Quack();
	Duck *mallard = new MallardDuck(pflybehavior,pQuackbehavior);
	mallard->performFly();
	mallard->performQuack();
	cin.get();
	return 0;
}

执行结果如下:

I'm flying!!

Quack

设计原则

        可扩张性:当有新类型鸭子加入时,只要让其继承Duck类,并添加相应的行为方法类,初始化式用需要的行为方法类来初始化即可。

        复用性:如会飞的鸭都可以用FlyWithWings。

        设计原则的应用:

        设计原则1:找出应用中可能需要变化之处,把他们独立出来,不要和哪些不需要变化的代码混在一起。(另外一种表述:将会变化的部分取出来并封装起来,好让其他部分不会受影响)。如上述例子中的FlyBehavior和QuackBehavior行为。

        设计原则2:针对接口编程,而不是针对实现编程。如上述例子中的FlyBehavior和QuackBehavior,它们的实现都将实现其中的一个接口,而鸭子基类不会负责实现FlyBehavior和QuackBehavior接口。

        设计原则3:多用组合,少用继承。如本例中,每一鸭子都有一个FlyBehavior和QuackBehavior

猜你喜欢

转载自blog.csdn.net/wfei101/article/details/80861832