天天看點

政策模式-1.簡單定義及一個執行個體

<!DOCTYPE html>
<html>
<head>
    <title>政策模式的定義</title>
</head>
<body>

</body>
<script type="text/javascript">
    //政策模式的定義
    //定義一系列的算法,把它們一個個封裝起來,并且使它們可以互相替換。

    /*
        例子:
        很多公司的年終獎是根據員工的工資基數和年底績效情況來發放的。例如,績效為 S的人年
        終獎有 4倍工資,績效為 A的人年終獎有 3倍工資,而績效為 B的人年終獎是 2倍工資。假設财
        務部要求我們提供一段代碼,來友善他們計算員工的年終獎。
    */
    //正常思維的實作

    var calculateBonus = function (performanceLevel, salary) {
        if (performanceLevel === 'S') {
            return salary*4;        
        } else if (performanceLevel === 'A') {
            return salary*3;
        } else if (performanceLevel === 'B') {
            return salary*2;
        }
    };
    console.log(calculateBonus('A', 200));
    /*
    缺點:
        1.calculateBonus 函數比較龐大,包含了很多 if-else 語句,這些語句需要覆寫所有的邏輯分支;
        2.calculateBonus 函數缺乏彈性,如果增加了一種新的績效等級 C,或者想把績效 S 的獎金系數改為 5,那我們必須深入  calculateBonus 函數的内部實作,這是違反開放封閉原則的。
        3.算法的複用性差,如果在程式的其他地方需要重用這些計算獎金的算法呢?我們的選擇隻有複制和粘貼
    */ 
    
    //改進版

    var performanceS = function (salary) {
        return salary*4;
    };

    var performanceA = function (salary) {
        return salary*3;
    };

    var performanceB = function (salary) {
        return salary*2;
    };

    var calculateBonus = function (performanceLevel, salary) {
        if (performanceLevel === 'S') {
            return performanceS(salary);
        }else if (performanceLevel === 'A') {
            return performanceA(salary);
        }else if (performanceLevel === 'B') {
            return performanceB(salary);
        }
    };

    calculateBonus('A', 200);

    //使用政策模式改進
    /*政策模式指的是定義一系列的算法,把它們一個個封裝起來。将不變的部分和變化的部分隔開是每個設計模式的主題,
      政策模式也不例外,政策模式的目的就是将算法的使用與算法的實作分離開來。

      一個基于政策模式的程式至少由兩部分組成。第一個部分是一組政策類,政策類封裝了具體
      的算法,并負責具體的計算過程。 第二個部分是環境類 Context,Context接受客戶的請求,随後
      把請求委托給某一個政策類。要做到這點,說明 Context中要維持對某個政策對象的引用
    */  

    var performanceS = function () {};
    performanceS.prototype.calculate = function (salary) {
        return salary*4;
    }

    var performanceA = function () {};
    performanceA.prototype.calculate = function (salary) {
        return salary*3;
    }

    var performanceB = function () {};
    performanceB.prototype.calculate = function (salary) {
        return salary*2;
    }

    //定義獎金類
    var Bonus = function () {
        this.salary = null;//原始工資
        this.strategy = null;//績效等級對應的政策對象
    };
    Bonus.prototype.setSalary = function (salary) {
        this.salary = salary;//設定員工的原始工資
    }
    Bonus.prototype.setStrategy = function (strategy) {
        this.strategy = strategy;//設定員工績效等級對應的政策對象
    }
    Bonus.prototype.getBonus = function () {
        return this.strategy.calculate( this.salary ); // 把計算獎金的操作委托給對應的政策對象
    }

    var bouns = new Bonus();
    bouns.setSalary(100);
    bouns.setStrategy(new performanceS());//設定政策對象
    console.log( bonus.getBonus() );

    bouns.setStrategy(new performanceA());//設定政策對象
    console.log( bonus.getBonus() );

    /*
        典型的Javascript版
    */
    var strategies = {
        "S": function( salary ){
            return salary * 4;
        },
        "A": function( salary ){
            return salary * 3;
        },
        "B": function( salary ){
            return salary * 2;
        }
    };
    var calculateBonus = function (level, salary) {
        return strategies[level](salary);
    }
    console.log( calculateBonus( 'S', 20000 ) ); // 輸出:80000
    console.log( calculateBonus( 'A', 10000 ) ); // 輸出:30000        


</script>
</html>      

轉載于:https://www.cnblogs.com/hanhui66/p/7110771.html

繼續閱讀