javascript设计模式 ? 职责链模式原理与用法实例分析


Posted in Javascript onApril 16, 2020

本文实例讲述了javascript设计模式 ? 职责链模式原理与用法。分享给大家供大家参考,具体如下:

介绍:很多情况下,在一个软件系统中可以处理某个请求的对象不止一个。例如一个网络请求过来,需要有对象去解析request Body,需要有对象去解析请求头,还需要有对象去对执行对应controller。请求一层层传递,让每一个对象都基于请求完成自己的任务,然后将请求传递给下一个处理程序。是不是感觉有点中间件的感觉。

定义:职责链就是避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求。将这些对象连成一条链,并沿着链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

场景:我们继续画圆,我们准备了两组示例:

示例:

var Circle = function(){
  this.radius = 0;
 
  this.drawByRadius = function(radius){
    if(radius < 5){
      this.drawVerySmalCircle();
    }else if(radius < 10){
      this.drawSmalCircle();
    }else if(radius < 15){
      this.drawMediumCircle();
    }else if(radius < 20){
      this.drawBigCircle();
    }else{
      this.drawVeryBigCircle();
    }
  }
 
  this.drawVerySmalCircle = function(){
    console.log('画一个超小的圆( 5以下 )');
  }
  this.drawSmalCircle = function(){
    console.log('画一个小圆( 5-10 )');
  }
  this.drawMediumCircle = function(){
    console.log('画一个中圆 ( 10-15 )');
  }
  this.drawBigCircle = function(){
    console.log('画一个大圆 ( 15-20 )');
  }
  this.drawVeryBigCircle = function(){
    console.log('画一个超大的圆 ( 20以上 )');
  }
}
 
var circle = new Circle();
circle.drawByRadius(30);
//画一个超大的圆 ( 20以上 )

观察上面的代码,这是很常见的逻辑,通过参数来决定执行哪个方法。首先drawByRadius方法职责过重,其次这样的方式在修改,新增时需要修改源代码,不符合开关原则。

我们使用职责链模式重写下:

var drawSmalCircle = function(min,max){
  this.max = max;
  this.min = min;
  this.nextCircle;
  this.setNextDraw = function(circle){
    this.nextCircle = circle;
  }
  this.draw = function(radius){
    console.log('执行:drawSmalCircle');
    if(this.min < radius && radius < this.max){
      console.log('画一个小圆( 10以下 )');
    }
    if(this.nextCircle){
      this.nextCircle.draw(radius)
    }
  }
}
 
var drawMediumCircle = function(min,max){
  this.max = max;
  this.min = min;
  this.nextCircle;
  this.setNextDraw = function(circle){
    this.nextCircle = circle;
  }
  this.draw = function(radius){
    console.log('执行:drawMediumCircle');
    if(this.min < radius && radius < this.max){
      console.log('画一个中圆 ( 10-20 )');
    }
    if(this.nextCircle){
      this.nextCircle.draw(radius)
    }
  }
}
 
var drawBigCircle = function(min,max){
  this.max = max;
  this.min = min;
  this.nextCircle;
  this.setNextDraw = function(circle){
    this.nextCircle = circle;
  }
  this.draw = function(radius){
    console.log('执行:drawBigCircle');
    if(this.min < radius && radius < this.max){
      console.log('画一个大圆 ( 20以上 )');
    }
    if(this.nextCircle){
      this.nextCircle.draw(radius)
    }
  }
}
 
function initChain(){
  var smalCircle = new drawSmalCircle(0,10);
  var mediumCircle = new drawMediumCircle(10,20);
  var bigCircle = new drawBigCircle(20,100);
 
  smalCircle.setNextDraw(mediumCircle);
  mediumCircle.setNextDraw(bigCircle);
  return smalCircle;
}
 
var circle = initChain();
circle.draw(30)
// 执行:drawSmalCircle
// 执行:drawMediumCircle
// 执行:drawBigCircle
// 画一个大圆 ( 20以上 
circle.draw(15)
// 执行:drawSmalCircle
// 执行:drawMediumCircle
// 画一个中圆 ( 10-20 )
// 执行:drawBigCircle
circle.draw(5)
// 执行:drawSmalCircle
// 画一个小圆( 10以下 )
// 执行:drawMediumCircle
// 执行:drawBigCircle

以上就是职责链模式的实例代码,drawSmalCircle,drawMediumCircle,drawBigCircle称为处理者类,处理者类保存了下一级对象的引用,

当我每执行一次draw时,程序会挨个执行职责链上的每一个方法。

职责链模式分为纯职责链和不纯职责链,纯的职责链在处理请求时,只能选择全部处理不传递或者全部传递不处理。我们这里的例子就是不纯职责链。它允许处理完成后继续向后传递。

职责链模式总结:

优点:
* 降低耦合,互相都不清楚执行顺序以及执行处理的类。
* 请求对象仅需维持一个指向其后继者的引用,简化了对象的相互连接。
* 新增修改职责链结构方便,满足开关原则。

缺点:
* 由于没有明确接受者,可能职责链走到最后都没有被正确处理。
* 职责链较长时会导致系统性能受影响。
* 建链不当,会造成循环调用,导致系统陷入死循环。

适用场景:
* 多个对象处理同一请求
* 动态创建执行顺序,流程

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript hashtable 修正版 下载
Dec 30 Javascript
javascript-简单的日历实现及Date对象语法介绍(附图)
May 30 Javascript
js数组循环遍历数组内所有元素的方法
Jan 18 Javascript
jquery实现省市select下拉框的替换(示例代码)
Feb 22 Javascript
扩展jQuery对象时如何扩展成员变量具体怎么实现
Apr 25 Javascript
基于javascript的COOkie的操作实现只能点一次
Dec 26 Javascript
js中的关联数组与普通数组详解
Jul 27 Javascript
JS去除重复并统计数量的实现方法
Dec 15 Javascript
使用Promise链式调用解决多个异步回调的问题
Jan 15 Javascript
解决vue-cli脚手架打包后vendor文件过大的问题
Sep 27 Javascript
通过GASP让vue实现动态效果实例代码详解
Nov 24 Javascript
Nest.js 授权验证的方法示例
Feb 22 Javascript
vue下canvas裁剪图片实例讲解
Apr 16 #Javascript
javascript设计模式 ? 代理模式原理与用法实例分析
Apr 16 #Javascript
js String.prototype.trim字符去前后空格的扩展
Aug 23 #Javascript
Vue Object 的变化侦测实现代码
Apr 15 #Javascript
Vue项目vscode 安装eslint插件的方法(代码自动修复)
Apr 15 #Javascript
小程序按钮避免多次调用接口和点击方案实现(不用showLoading)
Apr 15 #Javascript
javascript设计模式 ? 享元模式原理与用法实例分析
Apr 15 #Javascript
You might like
PHP实现上一篇下一篇的方法实例总结
2016/09/22 PHP
thinkPHP数据库增删改查操作方法实例详解
2016/12/06 PHP
PHP crc32()函数讲解
2019/02/14 PHP
PHP使用Http Post请求发送Json对象数据代码解析
2020/07/16 PHP
JS location几个方法小姐
2008/07/09 Javascript
JSON.parse 解析字符串出错的解决方法
2010/07/08 Javascript
在Ajax中使用Flash实现跨域数据读取的实现方法
2010/12/02 Javascript
快速排序 php与javascript的不同之处
2011/02/22 Javascript
nodejs 后缀名判断限制代码
2011/03/31 NodeJs
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
JavaScript实现给按钮加上双重动作的方法
2015/08/14 Javascript
学习JavaScript设计模式之状态模式
2016/01/08 Javascript
JS框架之vue.js(深入三:组件1)
2016/09/29 Javascript
JS中传递参数的几种不同方法比较
2017/01/20 Javascript
JavaScript 数据类型详解
2017/03/13 Javascript
使用python检测手机QQ在线状态的脚本代码
2013/02/10 Python
Python Trie树实现字典排序
2014/03/28 Python
python网络编程实例简析
2014/09/26 Python
python实现按行切分文本文件的方法
2016/04/18 Python
python pycharm的安装及其使用
2019/10/11 Python
keras打印loss对权重的导数方式
2020/06/10 Python
python实现mask矩阵示例(根据列表所给元素)
2020/07/30 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
2020/12/13 Python
HTML5之SVG 2D入门6—视窗坐标系与用户坐标系及变换概述
2013/01/30 HTML / CSS
HTML5实现晶莹剔透的雨滴特效
2014/05/14 HTML / CSS
浅析HTML5中header标签的用法
2016/06/24 HTML / CSS
Python中如何定义一个函数
2016/09/06 面试题
个人自我鉴定范文
2013/10/04 职场文书
交通事故协议书范文
2014/04/16 职场文书
圣诞节活动策划方案
2014/06/09 职场文书
学校学习雷锋活动总结
2014/07/03 职场文书
联谊活动总结
2014/08/28 职场文书
检察院对照“四风”认真查找问题落实整改措施
2014/09/26 职场文书
学习保证书100字
2015/02/26 职场文书
门店店长岗位职责
2015/04/14 职场文书
行政后勤人员工作计划应该怎么写?
2019/08/16 职场文书