JavaScript实现职责链模式概述


Posted in Javascript onJanuary 25, 2018

什么是职责链模式

职责链模式的定义是:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。举个例子:当你从公交车后门上车之后,你不可能直接把硬币放到收款箱里面, 因为你不知道它在哪,那你就只能把硬币给你前面一个人,让他帮你传到前面一个人手上,这样一直传递到站在收款箱旁边人的手上,由他把硬币放到收款箱里面。

职责链模式思想

请求发送者只需要知道链中的第一个节点,从而弱化了发送者和一组接收者之间的强联系。

JavaScript实现职责链模式(AOP方式)

Function.prototype.after = function(fn) {
  var _self = this;

  return function () {
    var ret = _self.apply(this, arguments);
    if(ret === "nextSuccessor") {
     return fn.apply(this, arguments);
    }
    return ret;
  }
 }

是的没错,在JavaScript中实现职责链模式就是如此的简单,如果对上面AOP代码不了解可以参考我之前写的这篇文章JavaScript实现AOP,这个方式和装饰者模式看起来很像,从代码上来看确实很像,但是他们的出发点是完全不同的

AOP实现装饰者模式:在不改变已有函数内部的情况下添加一些新的功能,你可以想象一下同心圆,你每调用一次after,就相当于给你的圆外面又加了一个圆来包裹住它。注意它们是包含关系

AOP实现职责链模式:在函数执行之后确定是否执行下一个函数,你每次调用after,都相当于在已有函数之后添加一个函数,至于是否执行后面这个函数,取决于前一个函数的返回值。注意它们是链式关系

职责链模式实例

function cat (type) {
  if(type == "cat") {
    console.log("我是猫猫");
  } else {
    return "nextSuccessor"
  }
}

function dog (type) {
  if(type == "dog") {
    console.log("我是狗狗");
  } else {
    return "nextSuccessor"
  }
}

function pig (type) {
  if(type == "pig") {
    console.log("我是猪猪");
  } else {
    return "nextSuccessor"
  }
}

Function.prototype.after = function(fn) {
  var _self = this;

  return function () {
    var ret = _self.apply(this, arguments);
    if(ret === "nextSuccessor") {
      return fn.apply(this, arguments);
    }
    return ret;
  }
}


var pet = cat.after(dog).after(pig);

pet("pig"); //我是猪猪
pet("dog"); //我是狗狗
pet("cat"); //我是猫猫

请看上述代码,我们给pet方法传入了三个不同的参数,得到了不同的结果。拿第一次调用举例,其执行过程是这样的:传入“pig”,先由cat方法判断,cat方法发现自己处理不了,于是把“pig”传递给dog方法(return "nextSuccessor"来表示传递给下一个函数),dog方法发现自己也处理不了,再接着把“pig”传递到pig方法,pig方法可以处理,控制台打印,我是猪猪。

你可能会觉得这不是浪费精神么,上述功能只需使用下面的几行代码就能解决,为何还要多写上面那么多代码

function pet(type) {
  if(type == "cat") {
    console.log("我是猫猫");
  } else if(type == "dog") {
    console.log("我是狗狗");
  } else if(type == "pig") {
    console.log("我是猪猪");
  }
}

pet("pig"); //我是猪猪
pet("dog"); //我是狗狗
pet("cat"); //我是猫猫

这样看来,好像是简单了很多。但是你有没有考虑过,如果以后突然多了猴子这种动物,如果使用上面的垃圾代码,那你就要去修改pet函数的源码,多添加一条if语句判断是不是猴子,其实这也还好,如果是加了1万种动物呢?那你就要在pet这个函数里添加1万条if语句,什么?还不够浮夸?那你有没有考虑过一种动物还会分很多品种,比如说猫咪分为长毛猫,短毛猫。这样你的代码就会涉及到嵌套if语句。恕我直言,现在你的代码已经丑成狗了,嘻嘻

但是如果使用职责链模式,每多一个种动物,我们就给他定义一个函数,然后添加到职责链上,这样一来,新的函数就和原来的函数高度解耦,岂不美哉?

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
找到一点可怜的关于dojo资料,谢谢作者!
Dec 06 Javascript
JS在IE和FireFox之间常用函数的区别小结
Mar 12 Javascript
JavaScript之HTMLCollection接口代码
Apr 27 Javascript
前端开发过程中浏览器版本的两种判定方法
Oct 30 Javascript
JavaScript获取网页中第一个图片id的方法
Apr 03 Javascript
JS日期格式化之javascript Date format
Oct 01 Javascript
Angular表单验证实例详解
Oct 20 Javascript
JavaScript定义全局对象的方法示例
Jan 12 Javascript
js数字舍入误差以及解决方法(必看篇)
Feb 28 Javascript
Bootstrap模态对话框用法简单示例
Aug 31 Javascript
Vue2(三)实现子菜单展开收缩,带动画效果实现方法
Apr 28 Javascript
Vue封装的组件全局注册并引用
Jul 24 Javascript
使用Ajax和Jquery配合数据库实现下拉框的二级联动的示例
Jan 25 #jQuery
解决Jquery下拉框数据动态获取的问题
Jan 25 #jQuery
vue引入新版 vue-awesome-swiper插件填坑问题
Jan 25 #Javascript
vue better-scroll插件使用详解
Jan 25 #Javascript
jquery 获取索引值在一定范围的列表方法
Jan 25 #jQuery
MUI 实现侧滑菜单及其主体部分上下滑动的方法
Jan 25 #Javascript
完美解决mui框架off-canvas侧滑超出部分隐藏无法滚动的问题
Jan 25 #Javascript
You might like
PHP Class&Object -- PHP 自排序二叉树的深入解析
2013/06/25 PHP
解析Win7 XAMPP apache无法启动的问题
2013/06/26 PHP
php截取字符串之截取utf8或gbk编码的中英文字符串示例
2014/03/12 PHP
PHP学习笔记(一):基本语法之标记、空白、和注释
2015/04/17 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
PHP模型Model类封装数据库操作示例
2019/03/14 PHP
javascript 面向对象继承
2009/11/26 Javascript
超级24小时弹窗代码 24小时退出弹窗代码 100%弹窗代码(IE only)
2010/06/11 Javascript
基于jquery的返回顶部效果(兼容IE6)
2011/01/17 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
JS计算网页停留时间代码
2014/04/28 Javascript
详解Javascript 装载和执行
2014/11/17 Javascript
js验证上传图片的方法
2015/05/12 Javascript
js的各种排序算法实现(总结)
2016/07/23 Javascript
快速掌握jQuery插件开发
2017/01/19 Javascript
用file标签实现多图文件上传预览
2017/02/14 Javascript
详解vue父子模版嵌套案例
2017/03/04 Javascript
基于Vue2的独立构建与运行时构建的差别(详解)
2017/12/06 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
2018/09/18 Javascript
微信jssdk逻辑在vue中的运用详解
2018/11/14 Javascript
Vue一个案例引发的递归组件的使用详解
2018/11/15 Javascript
基于three.js实现的3D粒子动效实例代码
2019/04/09 Javascript
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
2020/04/07 Javascript
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
python实现批量转换文件编码(批转换编码示例)
2014/01/23 Python
Python中if __name__ == '__main__'作用解析
2015/06/29 Python
解读python如何实现决策树算法
2018/10/11 Python
神经网络相关之基础概念的讲解
2018/12/29 Python
python代码编写计算器小程序
2020/03/30 Python
管理标语大全
2014/06/24 职场文书
2014应届本科生自我评价
2014/09/13 职场文书
锦旗赠语
2015/06/23 职场文书
2015年依法治校工作总结
2015/07/27 职场文书
祝福语集锦:朋友新店开业祝福语
2019/12/10 职场文书
Java 超详细讲解ThreadLocal类的使用
2022/04/07 Java/Android
Tomcat执行startup.bat出现闪退的原因及解决办法
2022/04/20 Servers