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 相关文章推荐
javascript getElementsByName()的用法说明
Jul 31 Javascript
javascript时间函数基础介绍
Mar 28 Javascript
js图片向右一张张滚动效果实例代码
Nov 23 Javascript
Document.location.href和.replace的区别示例介绍
Mar 04 Javascript
jQuery中innerHeight()方法用法实例
Jan 19 Javascript
jquery显示loading图片直到网页加载完成的方法
Jun 25 Javascript
JS实现网站菜单拖拽移位效果的方法
Sep 24 Javascript
jQuery使用$.ajax提交表单完整实例
Dec 11 Javascript
浅谈js使用in和hasOwnProperty获取对象属性的区别
Apr 27 Javascript
javascript将list转换成树状结构的实例
Sep 08 Javascript
mpvue 单文件页面配置详解
Dec 02 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
Jul 19 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编程之设置apache虚拟目录
2016/07/08 PHP
ThinkPHP中session函数详解
2016/09/14 PHP
php基于自定义函数记录log日志方法
2017/07/21 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
兼容多浏览器的iframe自适应高度(ie8 、谷歌浏览器4.0和 firefox3.5.3)
2009/11/04 Javascript
IE8下关于querySelectorAll()的问题
2010/05/13 Javascript
用js提交表单解决一个页面有多个提交按钮的问题
2014/09/01 Javascript
jQuery插件StickUp实现网页导航置顶
2015/04/12 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
js以分隔符分隔数组中的元素并转换为字符串的方法
2016/11/16 Javascript
微信小程序 网络请求(GET请求)详解
2016/11/16 Javascript
javascript 数组去重复(在线去重工具)
2016/12/17 Javascript
bootstrap table 表格中增加下拉菜单末行出现滚动条的快速解决方法
2017/01/05 Javascript
浅谈React中的元素、组件、实例和节点
2018/02/27 Javascript
详解Vue中watch的详细用法
2018/11/28 Javascript
Python版实现微信公众号扫码登陆
2020/05/28 Javascript
如何在JavaScript中正确处理变量
2020/12/25 Javascript
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
Python随机生成手机号、数字的方法详解
2017/07/21 Python
分数霸榜! python助你微信跳一跳拿高分
2018/01/08 Python
Python列表推导式与生成器表达式用法示例
2018/02/08 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
Python编程快速上手——强口令检测算法案例分析
2020/02/29 Python
Python中常见的数制转换有哪些
2020/05/27 Python
在Keras中实现保存和加载权重及模型结构
2020/06/15 Python
聊聊python中的异常嵌套
2020/09/01 Python
使用css3做0.5px的细线的示例代码
2018/01/18 HTML / CSS
德国内衣、泳装和睡衣网上商店:Bigsize Dessous
2018/07/09 全球购物
英国健身仓库:Bodybuilding Warehouse
2019/03/06 全球购物
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
navabi英国:设计师大码女装
2019/06/25 全球购物
财务部绩效考核方案
2014/05/04 职场文书
新闻发布会策划方案
2014/06/12 职场文书
2014年学生会工作总结范文
2014/11/07 职场文书
大学生干部培训心得体会
2016/01/06 职场文书
事业单位工作人员岗前培训心得体会
2016/01/08 职场文书