zoukankan      html  css  js  c++  java
  • [设计模式]策略模式

    [设计模式]策略模式

    所谓策略模式,就是一个类的行为或算法可以在运行时更改。

    常见的策略模式是在if··else if··· 这种语句下,且其if的需求是不断变动的。

     

    1. 反例代码

      这是一个税率计算器,根据各国的税率进行计算。说实话,如果我没学设计模式,我很可能就是写出如下代码,但是在使用设计模式之后,你会发现代码如此简洁。

      弊端非常明显,就是一旦你有了新的需求,就必须更改源码,另外,还有一个非常严重的就是大量if判断会严重占用内存。

    enum TaxBase {
        CN_Tax,
        US_Tax,
        DE_Tax,
        FR_Tax       //更改
    };
    
    class SalesOrder{
        TaxBase tax;
    public:
        double CalculateTax(){
            //...
            
            if (tax == CN_Tax){
                //CN***********
            }
            else if (tax == US_Tax){
                //US***********
            }
            else if (tax == DE_Tax){
                //DE***********
            }
            else if (tax == FR_Tax){  //更改
                //...
            }
    
            //....
         }
        
    }; 

    2. 策略模式

      我们修改上面代码的方法是使用策略方法,其核心原则是虚类在创建时动态绑定,至于绑定的对象,我们使用工厂方法来生产对应的策略。

       

    class TaxStrategy{
    public:
        virtual double Calculate(const Context& context)=0;
        virtual ~TaxStrategy(){}
    };
    
    
    class CNTax : public TaxStrategy{
    public:
        virtual double Calculate(const Context& context){
            //***********
        }
    };
    
    class USTax : public TaxStrategy{
    public:
        virtual double Calculate(const Context& context){
            //***********
        }
    };
    
    class DETax : public TaxStrategy{
    public:
        virtual double Calculate(const Context& context){
            //***********
        }
    };
    
    
    
    //扩展
    //*********************************
    class FRTax : public TaxStrategy{
    public:
        virtual double Calculate(const Context& context){
            //.........
        }
    };
    
    
    class SalesOrder{
    private:
        TaxStrategy* strategy;
    
    public:
        SalesOrder(StrategyFactory* strategyFactory){
            this->strategy = strategyFactory->NewStrategy();
        }
        ~SalesOrder(){
            delete this->strategy;
        }
    
        public double CalculateTax(){
            //...
            Context context();
            
            double val = 
                strategy->Calculate(context); //多态调用
            //...
        }
        
    };

    3. 一个实例化样例

    #include <iostream>
    using namespace std;
    
    // 税率策略类
    class TaxStrategy {
    public:
        virtual    double Calculate(const int& income) = 0; // 虚函数 
        virtual ~TaxStrategy() {}  // 基类的虚构函数必须使用虚函数
    };
    
    // 实例化中国的税率策略
    class ChineseTaxStrategy : public TaxStrategy {
    public:
        virtual double Calculate(const int& income) {
            return income * 1.1;
        }
    };
    
    // 实例化日本的税率策略
    class JapaneseTaxStrategy : public TaxStrategy {
    public:
        virtual double Calculate(const int& income) {
            return income * 1.2;
        }
    };
    
    // 税率工厂基类,具体产出使用哪一个类 
    class StrategyFactory {
    public:
        virtual TaxStrategy* CreateStrategy()=0;
        virtual ~StrategyFactory() {}
    };
    
    // 中国税率工厂
    class ChineseStrategyFactory :public StrategyFactory {
    public:
        virtual TaxStrategy* CreateStrategy() {
            return new ChineseTaxStrategy();
        }
    };
    
    //    日本税率工厂
    class JapaneseStrategyFactory :public StrategyFactory {
    public:
        virtual TaxStrategy* CreateStrategy() {
            return new JapaneseTaxStrategy();
        }
    };
    
    // 税率计算器
    class SalesOrder {
    private:
        TaxStrategy* strategy; // 待定使用哪一种计算方法
    public:
        SalesOrder(StrategyFactory* strategyFactory) {
            this->strategy = strategyFactory->CreateStrategy(); 
        }
        double calc(const int& income) {
            return strategy->Calculate(income);
        }
        ~SalesOrder() {
            delete strategy;
        }
    };
    
    // 主函数
    int main() {
        // 使用中国税率来进行计算
        ChineseStrategyFactory* p= new ChineseStrategyFactory();
        SalesOrder calculator(p);
        cout << calculator.calc(123) << endl;
    }
  • 相关阅读:
    【POJ】[1703]Find them, Catch them
    【杭电】[2717]Catch That Cow
    【杭电】[2717]Catch That Cow
    【杭电】[1716]排列2
    【杭电】[1716]排列2
    【杭电】[2084]数塔
    【杭电】[2084]数塔
    【杭电】[1003]Max Sum
    【杭电】[1003]Max Sum
    [leetcode]117. Populating Next Right Pointers in Each NodeII用next填充同层相邻节点
  • 原文地址:https://www.cnblogs.com/onetrainee/p/12729208.html
Copyright © 2011-2022 走看看