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 Title、alt提示(Tips)实现源码解读
Dec 12 Javascript
jquery如何改变html标签的样式(两种实现方法)
Jan 16 Javascript
js禁止页面使用右键(简单示例代码)
Nov 13 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
May 05 Javascript
jquery渐隐渐显的图片幻灯闪烁切换实现方法
Feb 26 Javascript
javaScript基础语法介绍
Feb 28 Javascript
基于jQuery创建鼠标悬停效果的方法
Mar 07 Javascript
ES6学习之变量的两种命名方法示例
Jul 18 Javascript
浅谈vue项目重构技术要点和总结
Jan 23 Javascript
详解vue 单页应用(spa)前端路由实现原理
Apr 04 Javascript
在小程序中集成redux/immutable/thunk第三方库的方法
Aug 12 Javascript
Nest.js 授权验证的方法示例
Feb 22 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 正则匹配函数体
2009/08/25 PHP
PHP创建桌面快捷方式的实例代码
2014/02/17 PHP
PHP中的use关键字概述
2014/07/23 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
用于自动添加Digg This!按钮的JavaScript
2006/12/23 Javascript
JavaScript入门教程(10) 认识其他对象
2009/01/31 Javascript
iframe自适应宽度、高度 ie6 7 8,firefox 3.86下测试通过
2010/07/29 Javascript
myFocus slide3D v1.1.0 使用方法与下载
2011/01/12 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(三)情景对话中仿打字机输出文字
2013/01/23 Javascript
探讨JavaScript中声明全局变量三种方式的异同
2013/12/03 Javascript
js取值中form.all和不加all的区别介绍
2014/01/20 Javascript
BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)
2016/08/17 Javascript
jQuery模拟Marquee实现无缝滚动效果完整实例
2016/09/29 Javascript
d3.js实现简单的网络拓扑图实例代码
2016/11/06 Javascript
原生javascript实现分页效果
2017/04/21 Javascript
vue实现点击展开点击收起效果
2018/04/27 Javascript
玩转Koa之koa-router原理解析
2018/12/29 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
2020/07/22 Javascript
js实现QQ邮箱邮件拖拽删除功能
2020/08/27 Javascript
jQuery实现购物车全功能
2021/01/11 jQuery
python线程锁(thread)学习示例
2013/12/04 Python
在Python中使用zlib模块进行数据压缩的教程
2015/06/26 Python
Python 中的 else详解
2016/04/23 Python
Python实现的三层BP神经网络算法示例
2018/02/07 Python
Django 实现将图片转为Base64,然后使用json传输
2020/03/27 Python
Python中有几个关键字
2020/06/04 Python
Python全局变量与global关键字常见错误解决方案
2020/10/05 Python
解决PyCharm无法使用lxml库的问题(图解)
2020/12/22 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
2021/03/03 Python
加拿大奢华时装品牌:Mackage
2018/01/10 全球购物
澳大利亚窗帘商店:Curtain Wonderland
2019/12/01 全球购物
校园摄影活动策划方案
2014/02/05 职场文书
委托协议书范本
2014/04/22 职场文书
二年级评语大全
2014/04/23 职场文书
医学求职自荐信
2014/06/21 职场文书
Java面试题冲刺第十七天--基础篇3
2021/08/07 面试题