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 相关文章推荐
使用Jquery Aajx访问WCF服务(GET、POST、PUT、DELETE)
Mar 16 Javascript
web性能优化之javascript性能调优
Dec 28 Javascript
浅析showModalDialog数据缓存问题(用禁止浏览器缓存解决)
Jul 09 Javascript
类似php的js数组的in_array函数自定义方法
Dec 27 Javascript
jQuery的DOM操作之删除节点示例
Jan 03 Javascript
php的文件上传入门教程(实例讲解)
Apr 10 Javascript
js实现浏览器窗口大小被改变时触发事件的方法
Feb 02 Javascript
js操作css属性实现div层展开关闭效果的方法
May 11 Javascript
JavaScript常用字符串与数组扩展函数小结
Apr 24 Javascript
微信小程序Redux绑定实例详解
Jun 07 Javascript
百度小程序自定义通用toast组件
Jul 17 Javascript
react实现antd线上主题动态切换功能
Aug 12 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设计模式 Visitor 访问者模式
2011/06/28 PHP
PHP定时任务获取微信access_token的方法
2016/10/10 PHP
PHP插件PHPMailer发送邮件功能
2017/02/28 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
2017/04/19 PHP
js利用div背景,做一个竖线的效果。
2008/11/22 Javascript
jQuery函数的等价原生函数代码示例
2013/05/27 Javascript
JSONP之我见
2015/03/24 Javascript
javascript实现动态改变层大小的方法
2015/05/14 Javascript
javascript绘制漂亮的心型线效果完整实例
2016/02/02 Javascript
js仿3366小游戏选字游戏
2016/04/14 Javascript
原生js封装二级城市下拉列表的实现代码
2016/06/16 Javascript
js中获取时间new Date()的全面介绍
2016/06/20 Javascript
JS动态给对象添加事件的简单方法
2016/07/19 Javascript
Js得到radiobuttonlist选中值的两种方法(推荐)
2016/08/25 Javascript
Bootstrap 手风琴菜单的实现代码
2017/01/20 Javascript
JavaScript数据结构之二叉树的删除算法示例
2017/04/13 Javascript
vue router下的html5 history在iis服务器上的设置方法
2017/10/18 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
2018/05/07 Javascript
Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
2018/08/24 Javascript
Vuex,iView UI面包屑导航使用扩展详解
2019/11/04 Javascript
vue-model实现简易计算器
2020/08/17 Javascript
代码讲解Python对Windows服务进行监控
2018/02/11 Python
python实现全盘扫描搜索功能的方法
2019/02/14 Python
python如何解析配置文件并应用到项目中
2019/06/27 Python
在pytorch中查看可训练参数的例子
2019/08/18 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
关于Tensorflow使用CPU报错的解决方式
2020/02/05 Python
TensorFlow使用Graph的基本操作的实现
2020/04/22 Python
python中常见错误及解决方法
2020/06/21 Python
Python爬虫教程之利用正则表达式匹配网页内容
2020/12/08 Python
详解Python中的GIL(全局解释器锁)详解及解决GIL的几种方案
2021/01/29 Python
面向对象编程的优势是什么
2015/12/17 面试题
什么是托管函数?托管函数有什么用?
2014/06/15 面试题
运动会拉拉队口号
2014/06/09 职场文书
四风问题原因分析及整改措施
2014/10/24 职场文书
企业群众路线教育实践活动心得体会
2014/11/03 职场文书