1. 程式人生 > >策略模式——C++實現

策略模式——C++實現

策略模式其實和簡單工廠模式很相似,在看《大話設計模式》這本書時,一開始也是一度弄混這兩個模式,關於簡單工廠模式的一個介紹以及C++程式碼可以參考上一篇文章點選開啟連結。策略模式和簡單工廠模式最主要的區別在於客戶端使用者需要操作幾個類,下面仍以加、減、乘、除計算來講解:


在上簡單工廠模式中,客戶端程式碼:

int main()  
  
{      
    double A, B;  
      
    char ch;  
      
    while (cin >> A >> ch >> B){  
          
        operation *op = factory::createOperator(ch);          //產生例項  
          
        op->setA(A);       //動態繫結  
          
        op->setB(B);           //動態繫結  
          
        cout << op->getResult() << endl;     //動態繫結  
          
    }     
}  

策略模式中客戶端程式碼:

int main()

{
    
    double A, B;
    
    char ch;
    
    while (cin >> A >> ch >> B){
        
        factory::createOperator(ch);
        
        cout<<factory::result(A,B)<<endl;
        
    }
    
}

從上述兩個客戶端程式碼可見:簡單工廠模式中,使用者需要操作factory、operation這兩個類;策略模式中,使用者只需要操作factory這個類。這就是簡單工廠模式和策略模式最主要的區別(至於為什麼要這樣,應該是根據不同的應用場景和需求來決定的吧,但是因為自己對實際應用場景瞭解太少,這裡就不胡亂寫了,只從理論上說說二者區別)

至於怎麼實現在策略模式中只操作一個類,其實很簡單,只需要修改工廠類factory,而不需要修改operation類及其子類,如下:

簡單工廠模式的factory類:

class factory{  
      
public:  
      
    factory(){ };  
      
    ~factory(){ };  
      
    static operation* createOperator(char c){  
          
        operation* op = NULL;     //基類指標  
          
        switch (c){  
                  
            case '+':  
                  
                op = new Add();  
                  
                break;  
                  
            case '-':  
                  
                op = new Sub();  
                  
                break;  
                  
            case '*':  
                  
                op = new Mul();  
                  
                break;  
                  
            case '/':  
                  
                op = new Div();  
                  
                break;  
                  
            default:  
                  
                break;  
                  
        }  
          
        return op;         
    }      
};  

策略模式的factory類;

class factory{
    
public:
    
    factory(){
        
    };
    
    ~factory(){
        
    };
 
    static void createOperator(char c){
        
        switch (c){
                
            case '+':
                
                op = new Add();
                
                break;
                
            case '-':
                
                op = new Sub();
                
                break;
                
            case '*':
                
                op = new Mul();
                
                break;
                
            case '/':
                
                op = new Div();
                
                break;
                
            default:
                
                break;
                
        }
        
    }
    
    static double result(double A, double B){
        
        op->setA(A);
        
        op->setB(B);
        
        return op->getResult();
    }
    
private:
    
    static operation* op;      //基類指標
    
};

從上述兩端程式碼可以看到,策略模式將對operation類的相關操作放到了factory類中,進而,策略模式下的客戶端只需要操作factory一個類即可。換言之,factory類中既要有一個函式負責產生operation類的例項,又要有一個函式來呼叫operation類中對應的方法,比如:

static double result(double A, double B){
        
        op->setA(A);
        
        op->setB(B);
        
        return op->getResult(); //呼叫operation類的getResult方法
    }

策略模式下加減乘除運算整體C++程式碼:

#include<iostream>

using namespace std;

class operation {
    
public:
    
    operation():A(0),B(0){
        
    }
    
    virtual ~operation(){
        
    }
    
    void setA(double x){
        
        A = x;
        
    }
    
    void setB(double y){
        
        B = y;
        
    }
    
    double getA(){
        
        return A;
        
    }
    
    double getB(){
        
        return B;
        
    }
    
    virtual double getResult() = 0;  //純虛擬函式
    
private:
    
    double A;
    
    double B;
    
    char ch;
    
};

class Add :public operation {
    
public:
    
    double getResult(){
        
        return getA() + getB();
        
    }
    
};

class Sub :public operation {
    
public:
    
    double getResult(){
        
        return getA() - getB();
        
    }
    
};

class Mul : public operation{
    
public:
    
    double getResult(){
        
        return getA()*getB();
        
    }
    
};

class Div :public operation{
    
public:
    
    double getResult(){
        
        if (getB() == 0){
            
            cout << "input error" << endl;
            
            return -1;
            
        }
        
        else return getA() / getB();
        
    }
    
};

class factory{
    
public:
    
    factory(){
        
    };
    
    ~factory(){
        
    };
 
    static void createOperator(char c){
        
        switch (c){
                
            case '+':
                
                op = new Add();
                
                break;
                
            case '-':
                
                op = new Sub();
                
                break;
                
            case '*':
                
                op = new Mul();
                
                break;
                
            case '/':
                
                op = new Div();
                
                break;
                
            default:
                
                break;
                
        }
        
    }
    
    static double result(double A, double B){
        
        op->setA(A);
        
        op->setB(B);
        
        return op->getResult();
    }
    
private:
    
    static operation* op;      //基類指標
    
};

operation* factory::op=NULL;

int main()

{
    
    double A, B;
    
    char ch;
    
    while (cin >> A >> ch >> B){
        
        factory::createOperator(ch);
        
        cout<<factory::result(A,B)<<endl;
        
    }
    
}