JavaScript 设计模式(二):策略模式

栏目: 后端 · 发布时间: 6年前

内容简介:策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换生活小栗子:诸葛锦囊

JavaScript 设计模式(二):策略模式

策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换

生活小栗子:诸葛锦囊

诸葛给刘备的锦囊妙计,遇到任何困难都有应对计策。策略模式实现的也是类似的场景。

再来一栗:给喜欢的女生买冰淇淋,事先不了解其喜好,只能集齐各种味道,总会命种。就是比较 “费钱”,这也是策略模式的缺点,需事先考虑所有应对场景。

模式特点

  1. 策略类:算法封装成独立的函数/对象
  2. 环境类:根据不同参数调用对应的策略函数/对象执行

模式实现

实现方式:一个基于策略模式的程序至少由两部分组成,第一个部分是一组策略类 Strategies(可变),策略类封装类具体的算法,并负责具体的计算过程。第二个部分是环境类 Context(不变), Context 接收客户的请求,随后把请求委托给某一个策略类。

假设我们一个开发团队,人员组成包括(开发组长,后端,前端,测试)。开发组长领取开发任务(不变),但具体的任务执行人员可根据类型划分(可变)。

比如开发任务有以下几项:

  1. 优化服务器缓存(后端任务)
  2. 优化首屏加载速度(前端任务)
  3. 完成系统并发测试(测试任务)

开发组长会根据任务类型,分发到对应的开发人员头上,组长不承担具体开发任务。所以每一个开发人员就承担 Strategy 的作用(独立的任务执行),而组长拥有并可支配所有开发人员的资源,充当 Context 的角色。团队每一个开发人员 “组合” 起来就是一个 Strategies 类(执行开发任务)。 这个 Strategies 是可变的,如果说后续开发任务需要安卓的、IOS的支持,只要添加安卓、IOS开发人员配置即可(可扩展)。

// 策略类(开发人员)
var Strategies = {
    "backend": function(task) {
        console.log('进行后端任务:', task);
    },
    "frontend": function(task) {
        console.log('进行前端任务:', task);
    },
    "testend": function(task) {
        console.log('进行测试任务:', task);
    }
};

//  环境类(开发组长)
var Context = function(type, task) {
    typeof Strategies[type] === 'function' && Strategies[type](task);
}

Context('backend', '优化服务器缓存');
Context('frontend', '优化首页加载速度');
Context('testend', '完成系统并发测试');

上述代码带来的好处:

  1. 算法独立封装,任务分发;
    开发组长不承担具体开发任务(只做顶层设计,不跟年轻人抢饭碗)
  2. 复用性更好,不局限于 Context 调用;
    开发人员不愁下家(去哪写代码都是写代码)

策略模式的另一个好处就是,消除了大部分的 if...else / switch...case 条件分支语句,代码阅读性提高。

// 没有使用策略模式的组长...
var Context = function(type, task) {
    if (type === 'backend') {
        // 把后端给我叫来
    } else if (type === 'frontend') {
        // 把前端给我叫来
    } else if (type === 'testend') {
        // 把测试给我叫来
    }
}

JavaScript 中,函数作为“一等公民“,也称“一等对象”。JavaScript 中 ”高阶函数“ 应用中,函数可被作为变量或参数进行传递或调用。因此在 JavaScript 中,我们可将算法封装成独立的函数,并将它作为参数传递给另一个函数调用。

// 封装独立的函数
var backend = function(task) {
    console.log('进行后端任务:', task);
};
var frontend = function(task) {
    console.log('进行前端任务:', task);
};
var testend = function(task) {
    console.log('进行测试任务:', task);
};

//  环境类(开发组长)
var Context = function(func, task) {
    typeof func === 'function' && func(task);
}

Context(backend, '优化服务器缓存');
Context(frontend, '优化首页加载速度');
Context(testend, '完成系统并发测试');

少了 Strategies 策略类的外层包裹,函数更加独立,并不妨碍其调用。使用函数替代策略类方式,正是我们日常开发中经常用到的 “隐形” 策略模式。

适用场景

  1. 多重条件语句判断,执行对应的算法场景
  2. 表单校验(validator)

优缺点

  • 优点:

    if...else/switch...case
    
  • 缺点:

    1. 增加了许多策略类或对象(开发人员职能划分明确,人员成本有所增加);
    2. 必须了解各个 Strategy 的不同点,违反 “最少知识原则”(组长手底下有对应的开发人员,才不用自己那么苦逼)

JavaScript设计模式整理系列正在更新中,敬请关注专栏"前端进击的巨人",获取实时更新。

参考文章

本文首发Github,期待Star!

https://github.com/ZengLingYong/blog

作者:以乐之名


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Amazon Web Services

Programming Amazon Web Services

James Murty / O'Reilly Media / 2008-3-25 / USD 49.99

Building on the success of its storefront and fulfillment services, Amazon now allows businesses to "rent" computing power, data storage and bandwidth on its vast network platform. This book demonstra......一起来看看 《Programming Amazon Web Services》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具