策略模式-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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值