现在的位置: 首页 > 综合 > 正文

行为模式之策略模式(Strategy Pattern)(C++实现)

2014年01月22日 ⁄ 综合 ⁄ 共 3291字 ⁄ 字号 评论关闭

策略模式(Strategy Pattern).

定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。Strategy模式将逻辑(算法)封装到一个类里面,通过组合的方式将具体算法的实现在组合对象中实现,通过委托的方式将抽象接口的实现委托给组合对象实现。

1.设计原则:

a.找出应用中的可能变化之处,把它们独立出来,不要和那些不需要变化的代码混起来。(系统的某部分的改变不会影响其他部分)。

b.针对接口编程(利用多态针对超类型(通常为抽象类)进行编程),而不是针对实现编程。把会变化的行为抽取出来变成单独的接口,构成行为类。

c.多用组合,少用继承.(鸭子的行为不是继承过来的而是通过行为对象组合过来的)


2继承和组合的优缺点:

 继承:

   a.优点:易于修改和扩展那些被复用的实现

   b.缺点:1)破坏了封装性,继承中父类的实现细节暴露给子类了;
2)“白盒”复用,原因在1)中;
3)当父类的实现更改时,其所有子类将不得不随之改变
4)从父类继承而来的实现在运行期间不能改变(编译期间就已经确定了)。

组合

a.优点:

1黑盒复用,因为被包含对象的内部细节对外是不可见的;2)封装性好,原因为1);

3)实现和抽象的依赖性很小(组合对象和被组合对象之间的依赖性小);

4)可以在运行期间动态定义实现(通过一个指向相同类型的指针,典型的是抽象

基类的指针)。

b.缺点:系统中对象过多。 从上面对比中我们可以看出,组合相比继承可以取得更好的效果,因此在面向对象的设计中的有一条很重要的原则就是:优先使用(对象)组合,而非(类)继承(Favor CompositionOver Inheritance


下面用C++实现《Head First设计模式》书中的鸭子模拟器的策略模式,类的关系图如下:



 头文件Duck.h

#ifndef _DUCK_H_
#define _DUCK_H_
#include "Behavior.h"
class Duck
{
public:
	Duck();
	~Duck();
	
	 void swim();   //所有的子类共有的行为
	 virtual void display();//子类必须覆盖
	 void performQuack();
	 void performFly();
     void setFlyBehavior(FlyBehavior *flyBehavior);
	 void setQuackBehavior(QuackBehavior *quackBehavior);

protected:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;

};

class MallardDuck:public Duck
{
public:
    MallardDuck();
	virtual ~MallardDuck();
	void display();
protected:

private:

};



#endif //_DUCK_H_

源文件Duck.CPP

#include "Duck.h"
#include <iostream>
using namespace std;
Duck::Duck()
{

}
Duck::~Duck()
{    
	if(!flyBehavior)
		delete flyBehavior;
	if(!quackBehavior)
		delete quackBehavior;

	cout<<"~Duck()....."<<endl;
}
void Duck::swim()
{
cout<<"All ducks float,even decoys...."<<endl;
}
void Duck::display()
{
	cout<<"Duck::display()"<<endl;
}
void Duck::performFly()
{
	flyBehavior->fly();
	
}

void Duck::performQuack()
{
	quackBehavior->quack();
}

MallardDuck::MallardDuck()
{
  quackBehavior=new Quack();
  flyBehavior=new FlyWithWings();
}
MallardDuck::~MallardDuck()
{
cout<<"~MallardDuck()...."<<endl;

}
void MallardDuck::display()
{
	cout<<"I am a Mallard duck...."<<endl;
}

void Duck::setFlyBehavior(FlyBehavior *flyBehavior)
{
	this->flyBehavior=flyBehavior;
}
void Duck::setQuackBehavior(QuackBehavior *quackBehavior)
{
	this->quackBehavior=quackBehavior;
}

头文件Behavior.h

#ifndef _BEHAVIOR_H_
#define _BEHAVIOR_H_
//抽象基类
class FlyBehavior
{
public:
	FlyBehavior();
    virtual ~FlyBehavior();
	virtual void fly()=0;

};

class QuackBehavior
{
   
public:
	virtual void quack()=0;
};

//鸭子飞的行为
class FlyWithWings:public FlyBehavior
{
public:
    FlyWithWings();
virtual ~FlyWithWings();
	void fly();

};
class FlyNoWay:public FlyBehavior
{
public:
	void fly();
};
//鸭子叫的行为
class Quack:public QuackBehavior
{
public:
	void quack();
};
class MuteQuack:public QuackBehavior
{
public:
	void quack();
};

#endif

源文件Behavior.CPP

#include "Behavior.h"
#include <iostream>
using namespace std;


FlyBehavior::FlyBehavior()
{
}
FlyBehavior::~FlyBehavior()
{
	cout<<"~FlyBehavior()"<<endl;
}


FlyWithWings::FlyWithWings()
{

}
FlyWithWings::~FlyWithWings()
{
cout<<"~~FlyWithWings()"<<endl;
}
void FlyWithWings::fly()
{
	cout<<"I am flying..."<<endl;
}
void FlyNoWay::fly()
{
cout<<"I can't fly..."<<endl;
}



void Quack::quack()
{
cout<<"I am Quack"<<endl;
}

void MuteQuack::quack()
{
	cout<<"I am  MuteQuack..."<<endl;

}

主函数main.CPP代码

#include "Duck.h"
#include "Behavior.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
	Duck * mallard=new MallardDuck();
	//mallard->setFlyBehavior(new FlyWithWings());
	mallard->display();
	mallard->swim();
	mallard->performFly();
	mallard->performQuack();
	mallard->setFlyBehavior(new FlyNoWay());
    mallard->performFly();
  if (NULL != mallard)
   delete mallard;
	return 0;
}

运行结果如下:


抱歉!评论已关闭.