当前位置:编程学习 > C/C++ >>

用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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,