JavaScript设想形式与开辟实践系列之战略形式

本系列为《JavaScript设想形式与开辟实践》(作者:曾探)进修总结,如想深切相识,请支撑作者原版

战略形式

战略形式的定义:定义一系列的算法,把它们一个个封装起来,而且使它们能够相互替换

举个抽象的例子,运用战略形式盘算奖金

营业需求:

  • 绩效为S的人年终奖有4倍工资

  • 绩效为A的人年终奖有3倍工资

  • 绩效为B的人年终奖有2倍工资

财务部愿望我们能够供应一段代码,轻易他们盘算员工的年终奖。

最初的代码完成

我们能够编写一个名为calculateBonus的函数来盘算员工的奖金数额,这个函数须要传入两个参数:工资数额绩效品级。代码以下:

var calculateBonus = function(performanceLevel, salary) {
    if (performanceLevel === 'S') {
        return salary * 4;
    }
    if (performanceLevel === 'A') {
        return salary * 3;
    }
    if (performanceLevel === 'B') {
        return salary * 2;
    }
};

calculateBonus('B', 20000); //输出:40000
calculateBonus('S', 6000); //输出:24000

能够发明,这段代码异常简朴,然则存在着不言而喻的瑕玷。

  1. calculateBonus函数比较巨大,包含了许多if语句,这些语句须要掩盖一切的逻辑分支

  2. calculateBonus函数缺少弹性,假如增添新的绩效品级,那我们必需深切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);
    }
    if (performanceLevel == 'A') {
        return performanceA(salary);
    }
    if (performanceLevel == 'B') {
        return performanceB(salary);
    }
};

calculateBonus('A', 10000);//输出:30000

我们的顺序得到了肯定的改良,但我们依旧没有解决最主要的问题:calculateBonus函数有能够越来越庞大,而且在系统变化的时候缺少弹性。

运用战略形式重构代码

将稳定的部份和变化的部份离隔是每一个设想形式的主题,战略形式也不破例,战略形式的目标就是将算法的运用与算法的完成星散开来

一个基于战略形式的顺序最少由两部份构成,第一部份是一组战略类,战略类封装了细致的算法,并担任细致的盘算历程。第二部份是环境类Context接收客户的要求,随后把要求托付给某一个战略类

如今我们用战略形式来重构上边的代码。

//我们先把每种绩效的盘算划定规矩封装在对应的战略类里
var porformanceS = function() {};
porformanceS.prototype.calculate = function(salary) {
    return salary * 4;
};
var porformanceA = function() {};
porformanceA.prototype.calculate = function(salary) {
    return salary * 3;
};
var porformanceB = function() {};
porformanceB.prototype.calculate = function(salary) {
    return salary * 2;
};
//接下来定义奖金类Bonus:
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);
}

在完成最终的代码之前,我们再来回顾一下战略形式的头脑

定义一系列的算法,把它们一个个封装起来,并且使它们能够相互替换。

假如说的更细致一点,就是:定义一系列的算法,把它们各自封装成战略类,算法被封装在战略类内部的要领里。在客户对Context提议要求的时刻,Context老是把要求托付给这些战略对象中的某一个举行盘算。
我们继承完成适才的代码:

var Bonus = new Bonus();
bonus.setSalary(1000);
bonus.setStrategy(new performanceS());
bonus.getBonus();

JavaScript版本的战略形式

上述代码是模拟了一些传统的面向对象言语的完成,实际上在JavaScript中,函数也是对象,所以更简朴和直接的做法是把strategy直接定义为函数:

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);
};

总结

在JavaScript言语中,战略类每每被函数所替换,这是战略形式就成为了一种隐形的形式。只管如许,完全相识战略形式,也有助于我们邃晓运用函数的优点。

    原文作者:司想君
    原文地址: https://segmentfault.com/a/1190000004574435
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞