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 相关文章推荐
常用参考资料(手册)下载或者链接
Jul 22 Javascript
Jquery 自定义动画概述及示例
Mar 29 Javascript
JS 精确统计网站访问量的实例代码
Jul 05 Javascript
js拖拽一些常见的思路方法整理
Mar 19 Javascript
javascript获取当前鼠标坐标的方法
Jan 10 Javascript
javascript+ajax实现产品页面加载信息
Jul 09 Javascript
SWFObject基本用法实例分析
Jul 20 Javascript
基于jquery编写分页插件
Mar 07 Javascript
利用JQuery实现datatables插件的增加和删除行功能
Jan 06 Javascript
浅谈ng-zorro使用心得
Dec 03 Javascript
使用p5.js实现动态GIF图片临摹重现
Oct 23 Javascript
原生js实现下拉选项卡
Nov 27 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
在任意字符集下正常显示网页的方法一
2007/04/01 PHP
PHP实现多条件查询实例代码
2010/07/17 PHP
php连接odbc数据源并保存与查询数据的方法
2014/12/24 PHP
PHP实现用户登录的案例代码
2018/05/10 PHP
JavaScript加密解密7种方法总结分析
2007/10/07 Javascript
理清apply(),call()的区别和关系
2011/08/14 Javascript
javascript读写XML实现广告轮换(兼容IE、FF)
2013/08/09 Javascript
javascript实现文本域写入字符时限定字数
2014/02/12 Javascript
基于Bootstrap的Metronic框架实现条码和二维码的生成及打印处理操作
2016/08/29 Javascript
AngularJS通过$location获取及改变当前页面的URL
2016/09/23 Javascript
浅谈javascript:两种注释,声明变量,定义函数
2016/09/29 Javascript
jQuery旋转插件jqueryrotate用法详解
2016/10/13 Javascript
jQuery Ajax请求后台数据并在前台接收
2016/12/10 Javascript
Jquery Easyui分割按钮组件SplitButton使用详解(17)
2016/12/18 Javascript
js下载文件并修改文件名
2017/05/08 Javascript
基于Vue实现页面切换左右滑动效果
2020/06/29 Javascript
js微信分享实现代码
2020/10/11 Javascript
React通过父组件传递类名给子组件的实现方法
2017/11/13 Javascript
记一次Vue.js混入mixin的使用(分权限管理页面)
2019/04/17 Javascript
在Node.js中将SVG图像转换为PNG,JPEG,TIFF,WEBP和HEIF格式的方法
2019/08/22 Javascript
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
[01:00:06]加油DOTA_EP01_网络版
2014/08/09 DOTA
[32:26]EG vs IG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python函数装饰器用法实例详解
2015/06/04 Python
详解用TensorFlow实现逻辑回归算法
2018/05/02 Python
通过实例解析python描述符原理作用
2020/01/22 Python
Anaconda的安装及其环境变量的配置详解
2020/04/22 Python
python给list排序的简单方法
2020/12/10 Python
html5贪吃蛇游戏使用63行代码完美实现
2013/06/25 HTML / CSS
产品开发计划书
2014/04/27 职场文书
党员承诺书范文
2014/05/19 职场文书
先进个人事迹材料(2016推荐版)
2016/03/01 职场文书
原生Js 实现的简单无缝滚动轮播图的示例代码
2021/05/10 Javascript
简单介绍Python的第三方库yaml
2021/06/18 Python
分析MySQL优化 index merge 后引起的死锁
2022/04/19 MySQL
使用HBuilder制作一个简单的HTML5网页
2022/07/07 HTML / CSS