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

用C++实现设计模式中的策略模式

2012年06月28日 ⁄ 综合 ⁄ 共 2114字 ⁄ 字号 评论关闭

 

最近在看设计模式(Head First那本),这本书写的很不错,唯一的缺点是整本书都是用JAVA语言写的,JAVA虽然和C++一样都是面向对象的,但是有些术语还是不一样的,例如JAVA里面有“接口”这个术语,而在C++里面没有。不过好在这些模式C++应该都可以实现。

在第一章的策略模式中,讲到鸭子这个例子,这是一个很经典的例子,相信在软件开发中一定能经常遇到。把不变的东西和变化的东西进行分离,这样在以后的修改或添加新功能时能节省不少时间。下面我来尝试下用C++实现策略模式,由于能力有限,其中可能存在一些问题,欢迎指出提出修改意见,在此虚心接受。

下面就开始说鸭子吧。这里为了简化起见,只假设有fly这个需要变化的情况,至于鸭子会不会叫暂时假定都会。
按照书上的描述,要把duck和fly进行分离,JAVA中是把fly作为接口,在C++中我把fly作为一个抽象类,和书中描述的一样,这两个类是平级的。duck类中有鸭子的一些共有的不变的行为,fly类中包含两个抽象函数来设置飞行与否,除了这两个类以外,我还加入cn_duck(中国鸭子)这个类,以及duck_fly这个类,中国鸭子是鸭子的一种,姑且不论实际情况会不会飞,反正我们想让它飞他就飞了,duck_fly是把fly类里面的虚函数进行具体化。具体类图结构如下:

 


见图1

 

 

 

由上图可以看到,cn_duck类继承duck类,故其能够调用duck类中的方法,同时duck类与fly类有接口通信,这样cn_duck类也能调用fly类中的方法,前提是要给cn_duck类传递一个duck_fly类的对象。当需要添加更多的飞行时,可以在和duck_fly类平级上进行添加类,例如添加一个火箭飞行类。而在添加鸭子类型时,可以在cn_duck类平级上进行添加类,例如添加一个美国鸭子。这就是我理解的策略模式。不需要修改duck类,在用其他方法飞行时,也不需要修改fly类(除非添加除了飞行方法但是和飞行有关的行为,例如把鸭子翅膀添加到飞行中去,中国鸭子钢翅膀nb鸭子)。下面给出工程的代码,欢迎拍砖。

 

 

//duck.h

#include "fly.h"

class duck
{
public:
	void quack();
	void swim();
	virtual void display();

	fly *fy;

	void set_fly(fly *fy);


};

 

//duck.cpp

#include "duck.h"
#include <iostream>

using namespace std;

void duck::quack()
{
	cout<<"我在呱呱叫"<<endl;
}

void duck::swim()
{
	cout<<"我在游泳"<<endl;
}

void duck::display()
{
	cout<<"我是普通鸭子黄色嘴巴"<<endl;
}

void duck::set_fly(fly *fy)
{
	this->fy=fy;
}

 

 

//fly.h

#ifndef FLY_EGG
#define FLY_EGG

class fly
{
public:
	virtual void can_fly()=0;
	virtual void no_fly()=0;
	virtual void fly_way()=0;
};

#endif

 

//duck_fly.h

#include <iostream>
#include "fly.h"

using namespace std;

class duck_fly: public fly
{
public:
	void can_fly()
	{
		cout<<"duck fly!"<<endl;

	}

	void no_fly()
	{
		cout<<"duck not fly!"<<endl;
	}

	void fly_way()
	{
		cout<<"fly with wings"<<endl;
	}
};

 

//cn_duck.h

#include "duck.h"

class cn_duck:public duck
{
public:
	cn_duck();
	void display();
};

 

//cn_duck.cpp

#include "cn-duck.h"
#include <iostream>

using namespace std;

cn_duck::cn_duck()
{
	fy=NULL;
}

void cn_duck::display()
{
	cout<<"我是红嘴巴"<<endl;
}

 

//main.cpp

#include "cn-duck.h"
#include "duck_fly.h"

int main()
{
	//给定接口,表明是duck飞
	duck_fly *df=new duck_fly();

	cn_duck cd;
	cd.set_fly(df);//设定会飞
	cd.fy->can_fly();//调用duck_fly里的飞行
	cd.fy->fly_way();//调用飞行方法

	return 0;
}

 

 

上面就是我的理解,欢迎提出改进意见,当然程序有点问题,就是如果没有把duck_fly对象给cn_duck时,程序没有提示,但是会报错,不过按情理来说报错也是正常的,鸭子不会非肯定报错。

 

下面是程序运行界面:

 

 

最后还是说一句,欢迎提出意见,指出可以改正之处,谢谢。

抱歉!评论已关闭.