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

Design Patterns---- Strategy 模式

編輯:C++入門知識

設計模式:可復用面向對象軟件的基礎 書中對 Strategy 模式的定義如下:

定義了一系列的算法,把它們一個個封裝起來,並且使它們可相互替換。本模式使得算法可獨立於它的用戶而變化。


案例:設計一個商場收銀軟件,營業員根據客戶所購買商品的單價和數量,向客戶收費。商場有許多促銷的策略,打折,滿300減100等。。。

1. 如果采用之前將的工廠模式,可以采用如下的方式編寫:

// Last Update:2014-03-17 21:05:53
/**
 * @file cash.h
 * @brief Strategy Pattern
 * @author [email protected]
 * @version 0.1.00
 * @date 2014-03-17
 */

#ifndef CASH_H
#define CASH_H

#include 
#include 
#include 
#include 

// base class
// define interface
class CashSuper
{
public:
    virtual ~CashSuper() {}
    virtual double acceptCash(double money) = 0;
};

class CashNormal : public CashSuper
{
public:
    double acceptCash(double money){
        return money;
    }
};

class CashRebate : public CashSuper{
public:
    CashRebate(std::string moneyRate = "0.0"){
        std::stringstream s(moneyRate);
        s >> this->moneyRate_;
    }

    double acceptCash(double money){
        return money * moneyRate_; 
    }

private:
    double moneyRate_;
};

class CashReturn : public CashSuper{
public:
    CashReturn(std::string moneyCondition, std::string moneyReturn){
        std::stringstream s(moneyCondition);
        s >> this->moneyCondition_;
        std::stringstream s2(moneyReturn);
        s2 >> this->moneyReturn_;
    }

    double acceptCash(double money){
        if(money >= moneyCondition_){
            money -= std::floor(money / moneyCondition_) * moneyReturn_;
        }
        return money;
    }
private:
    double moneyCondition_, moneyReturn_;
};

// factory class
class CashFactory{
public:
    static CashSuper* createCashSuper(std::string type)
    {
        CashSuper *pCashSuper(NULL);

        if(type == "正常收費"){
            pCashSuper = new CashNormal();
        }
        else if(type == "滿300減100"){ 
            pCashSuper = new CashReturn("300", "100");
        }
        else if(type == "打8折"){ 
            pCashSuper = new CashRebate("0.8");
        }
        else{
            return NULL;
        }
        return pCashSuper;
    }
};

#endif  /*CASH_H*/



#include "cash.h"
#include 
#include "boost/shared_ptr.hpp"
using namespace std;

int main(void)
{
    boost::shared_ptr pCashSuper(CashFactory::createCashSuper("正常收費"));
    cout << pCashSuper->acceptCash(300) << endl;

    pCashSuper = boost::shared_ptr(CashFactory::createCashSuper("打8折"));
    cout << pCashSuper->acceptCash(300) << endl;

    pCashSuper = boost::shared_ptr(CashFactory::createCashSuper("滿300減100"));
    cout << pCashSuper->acceptCash(300) << endl;

    return 0;
}



2. Strategy 模式

策略模式可以減少各種算法類與使用算法類之間的耦合;

簡化單元測試,因為每個算法都有自己的類,可以通過自己的接口進行單元測試。

// base class
// define interface
class CashSuper
{
public:
    virtual ~CashSuper() {}
    virtual double acceptCash(double money) = 0;
};

class CashNormal : public CashSuper
{
public:
    double acceptCash(double money){
        return money;
    }
};

class CashRebate : public CashSuper{
public:
    CashRebate(std::string moneyRate = "0.0"){
        std::stringstream s(moneyRate);
        s >> this->moneyRate_;
    }

    double acceptCash(double money){
        return money * moneyRate_; 
    }
private:
    double moneyRate_;
};

class CashReturn : public CashSuper{
public:
    CashReturn(std::string moneyCondition, std::string moneyReturn){
        std::stringstream s(moneyCondition);
        s >> this->moneyCondition_;
        std::stringstream s2(moneyReturn);
        s2 >> this->moneyReturn_;
    }

    double acceptCash(double money){
        if(money >= moneyCondition_){
            money -= std::floor(money / moneyCondition_) * moneyReturn_;
        }
        return money;
    }
private:
    double moneyCondition_, moneyReturn_;
};

class CashContext{
public:
    CashContext(std::string type): pCashSuper_(NULL){
        if(type == "正常收費"){
            pCashSuper_ = new CashNormal;
        }
        else if(type == "滿300減100"){ 
            pCashSuper_ = new CashReturn("300", "100");
        }
        else if(type == "打8折"){ 
            pCashSuper_ = new CashRebate("0.8");
        }
        // else
    }

    ~CashContext(){
        if(pCashSuper_)
          delete pCashSuper_;
    }
    
    double GetResult(double money){
        assert(pCashSuper_ != NULL); 
        return pCashSuper_->acceptCash(money);
    }
private:
    CashSuper *pCashSuper_;
    // copy not allowed
    CashContext(const CashContext&);
    CashContext& operator=(const CashContext&);
};


// 客戶端使用如下:
    CashContext csuper("滿300減100");
    cout << csuper.GetResult(300) << endl; 

 




參考資料:

1. 大話設計模式

2. 設計模式:可復用面向對象軟件的基礎


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