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 相关文章推荐
游戏人文件夹程序 ver 3.0
Jul 14 Javascript
ASP小贴士/ASP Tips javascript tips可以当桌面
Dec 10 Javascript
页面只有一个text的时候,回车自动submit的解决方法
Aug 12 Javascript
【经典源码收藏】jQuery实用代码片段(筛选,搜索,样式,清除默认值,多选等)
Jun 07 Javascript
详解RequireJS按需加载样式文件
Apr 12 Javascript
详解用vue编写弹出框组件
Jul 04 Javascript
微信小程序中使用ECharts 异步加载数据的方法
Jun 27 Javascript
使用mixins实现elementUI表单全局验证的解决方法
Apr 02 Javascript
js如何实现元素曝光上报
Aug 07 Javascript
vue使用nprogress实现进度条
Dec 09 Javascript
微信小程序实现下滑到底部自动翻页功能
Mar 07 Javascript
Vue操作Storage本地化存储
Apr 29 Vue.js
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中类的学习
2008/03/28 PHP
php+javascript的日历控件
2009/11/19 PHP
php编程中echo用逗号和用点号连接的区别
2016/03/26 PHP
PHP时间相关常用函数用法示例
2020/06/03 PHP
JQuery插件fancybox无法在弹出层使用左右键的解决办法
2013/12/25 Javascript
深入分析Javascript跨域问题
2015/04/17 Javascript
浅谈下拉菜单中的Option对象
2015/05/10 Javascript
JavaScript文本框脚本编写的注意事项
2016/01/25 Javascript
快速掌握Node.js环境的安装与运行方法
2016/02/16 Javascript
jQuery EasyUI编辑DataGrid用combobox实现多级联动
2016/08/29 Javascript
纯js的右下角弹窗实例
2017/03/12 Javascript
微信小程序tabBar模板用法实例分析【附demo源码下载】
2017/11/28 Javascript
vue的全局提示框组件实例代码
2018/02/26 Javascript
vue后台管理之动态加载路由的方法
2018/08/13 Javascript
vue 图片裁剪上传组件的实现
2020/11/12 Javascript
[01:47]2018年度DOTA2最具人气解说-完美盛典
2018/12/16 DOTA
一个基于flask的web应用诞生(1)
2017/04/11 Python
python SSH模块登录,远程机执行shell命令实例解析
2018/01/12 Python
Python及Django框架生成二维码的方法分析
2018/01/31 Python
python对excel文档去重及求和的实例
2018/04/18 Python
浅谈Python采集网页时正则表达式匹配换行符的问题
2018/12/20 Python
利用Pyhton中的requests包进行网页访问测试的方法
2018/12/26 Python
python 与服务器的共享文件夹交互方法
2018/12/27 Python
python openCV获取人脸部分并存储功能
2019/08/28 Python
python统计文章中单词出现次数实例
2020/02/27 Python
python录音并调用百度语音识别接口的示例
2020/12/01 Python
电气工程师岗位职责
2014/01/01 职场文书
公司承诺书格式
2014/05/21 职场文书
公司应聘自荐书
2014/06/14 职场文书
暑假社会实践心得体会
2014/09/02 职场文书
高中生旷课检讨书
2014/10/08 职场文书
2014大学辅导员工作总结
2014/12/02 职场文书
留学推荐信怎么写
2015/03/26 职场文书
妈妈别哭观后感
2015/06/08 职场文书
保险公司增员口号
2015/12/25 职场文书
MySQL 中如何归档数据的实现方法
2022/03/16 SQL Server