程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 用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"  
 
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; 

//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時,程序沒有提示,但是會報錯,不過按情理來說報錯也是正常的,鴨子不會非肯定報錯。

 

下面是程序運行界面:

 \

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved