用C++实现设计模式中的策略模式
最近在看设计模式(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鸭子)。下面给出工程的代码,欢迎拍砖。
view plaincopy to clipboardprint?
//duck.h
#include "fly.h"
class duck
{
public:
void quack();
void swim();
virtual void display();
fly *fy;
void set_fly(fly *fy);
};
//duck.h
#include "fly.h"
class duck
{
public:
void quack();
void swim();
virtual void display();
fly *fy;
void set_fly(fly *fy);
};
view plaincopy to clipboardprint?
//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;
}
//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;
}
view plaincopy to clipboardprint?
//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
//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
view plaincopy to clipboardprint?
//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;
}
};
//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;
}
};
view plaincopy to clipboardprint?
//cn_duck.h
#include "duck.h"
class cn_duck:public duck
{
public:
cn_duck();
void display();
};
//cn_duck.h
#include "duck.h"
class cn_duck:public duck
{
public:
cn_duck();
void display();
};
view plaincopy to clipboardprint?
//cn_duck.cpp
#include "cn-duck.h"
#include <iostream>
using namespace std;
cn_duck::cn_duck()
{
fy=NULL;
}
void cn_duck::display()
{
cout<<"我是红嘴巴"<<endl;
}
//cn_duck.cpp
#include "cn-duck.h"
#include <iostream>
using namespace std;
cn_duck::cn_duck()
{
fy=NULL;
}
void cn_duck::display()
{
cout<<"我是红嘴巴"<<endl;
}
view plaincopy to clipboardprint?
//main.cpp
#include "cn-duck.h"
#include "duck_fly.h"
i
补充:软件开发 , C++ ,