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 相关文章推荐
用js实现随机返回数组的一个元素
Aug 13 Javascript
js 调整select 位置的函数
Feb 21 Javascript
Mootools 1.2教程 选项卡效果(Tabs)
Sep 15 Javascript
javascript天然的迭代器
Oct 29 Javascript
showModelDialog弹出文件下载窗口的使用示例
Nov 19 Javascript
javascript先序遍历DOM树的方法
Feb 27 Javascript
浅谈js内置对象Math的属性和方法(推荐)
Sep 19 Javascript
jQuery插件ajaxFileUpload使用详解
Jan 10 Javascript
angular中的http拦截器Interceptors的实现
Feb 21 Javascript
jQuery插件FusionWidgets实现的Cylinder图效果示例【附demo源码】
Mar 23 jQuery
Bootstrap Tree View简单而优雅的树结构组件实例解析
Jun 15 Javascript
原生JS实现pc端轮播图效果
Dec 21 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
PHP5/ZendEngine2的改进
2006/10/09 PHP
深入phpMyAdmin的安装与配置的详细步骤
2013/05/07 PHP
PHP实现无限级分类(不使用递归)
2015/10/22 PHP
Yii2框架控制器、路由、Url生成操作示例
2019/05/27 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
2019/10/12 PHP
EXTJS记事本 当CompositeField遇上RowEditor
2011/07/31 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
用示例说明filter()与find()的用法以及children()与find()的区别分析
2013/04/26 Javascript
让页面上两个div中的滚动条(滑块)同步运动示例
2013/08/07 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
2013/10/22 Javascript
JS的get和set使用示例
2014/02/20 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
2015/11/19 Javascript
bootstrap fileinput完整实例分享
2016/11/08 Javascript
Bootstrap基本布局实现方法详解
2016/11/25 Javascript
JavaScript实现图片瀑布流和底部刷新
2017/01/02 Javascript
详解JS中的快速排序与冒泡
2017/01/10 Javascript
Vue+axios 实现http拦截及路由拦截实例
2017/04/25 Javascript
jQuery返回定位插件详解
2017/05/15 jQuery
vue2.0移除或更改的一些东西(移除index key)
2017/08/28 Javascript
浅谈vuex之mutation和action的基本使用
2017/08/29 Javascript
Vue页面跳转动画效果的实现方法
2018/09/23 Javascript
JavaScript动态添加数据到表单并提交的几种方式
2019/06/26 Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
2019/09/14 Javascript
浅谈element中InfiniteScroll按需引入的一点注意事项
2020/06/05 Javascript
Vue解决echart在element的tab切换时显示不正确问题
2020/08/03 Javascript
antd design table更改某行数据的样式操作
2020/10/31 Javascript
Python scipy的二维图像卷积运算与图像模糊处理操作示例
2019/09/06 Python
基于python调用psutil模块过程解析
2019/12/20 Python
Django中ORM的基本使用教程
2020/12/22 Python
我的求职择业计划书
2014/04/04 职场文书
法人代表授权委托书
2014/04/08 职场文书
2014年超市员工工作总结
2014/11/18 职场文书
2015年教师学期工作总结
2015/04/30 职场文书
2015年税务稽查工作总结
2015/05/26 职场文书
mysql 乱码 字符集latin1转UTF8
2022/04/19 MySQL