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方法和技巧大全
Dec 27 Javascript
ext读取两种结构的xml的代码
Nov 05 Javascript
js中top、clientTop、scrollTop、offsetTop的区别 文字详细说明版
Jan 08 Javascript
Jquery为单选框checkbox绑定单击click事件
Dec 18 Javascript
javascript页面动态显示时间变化示例代码
Dec 18 Javascript
JS平滑无缝滚动效果的实现代码
May 06 Javascript
Bootstrap源码解读下拉菜单(4)
Dec 23 Javascript
bootstrap选项卡扩展功能详解
Jun 14 Javascript
Vue.js常用指令之循环使用v-for指令教程
Jun 27 Javascript
微信小程序 腾讯地图SDK 获取当前地址实现解析
Aug 12 Javascript
vue在图片上传的时候压缩图片
Nov 18 Vue.js
JavaScript如何利用Promise控制并发请求个数
May 14 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+javascript实现二级级联菜单的制作
2008/05/06 PHP
PHP中文编码小技巧
2014/12/25 PHP
thinkphp如何获取客户端IP
2015/11/03 PHP
PHP 等比例缩放图片详解及实例代码
2016/09/18 PHP
原生PHP实现导出csv格式Excel文件的方法示例【附源码下载】
2019/03/07 PHP
JavaScript与C# Windows应用程序交互方法
2007/06/29 Javascript
jQuery点击tr实现checkbox选中的方法
2013/03/19 Javascript
关于JavaScript与HTML的交互事件
2013/04/12 Javascript
页面加载完后自动执行一个方法的js代码
2014/09/06 Javascript
不使用ajax实现无刷新提交表单
2014/12/21 Javascript
详解JavaScript的变量和数据类型
2015/11/27 Javascript
详解打造 Vue.js 可复用组件
2017/03/24 Javascript
详解Vuejs2.0之异步跨域请求
2017/04/20 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
使用vue与jquery实时监听用户输入状态的操作代码
2017/09/19 jQuery
JS实现的小火箭发射动画效果示例
2018/12/08 Javascript
详解es6新增数组方法简便了哪些操作
2019/05/09 Javascript
我要点爆”微信小程序云开发之项目建立与我的页面功能实现
2019/05/26 Javascript
解决layui checkbox 提交多个值的问题
2019/09/02 Javascript
Python实现拼接多张图片的方法
2014/12/01 Python
Python基于PycURL实现POST的方法
2015/07/25 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
2018/06/14 Python
如何在Django项目中引入静态文件
2019/07/26 Python
python关闭占用端口方式
2019/12/17 Python
使用python-cv2实现视频的分解与合成的示例代码
2020/10/26 Python
详解利用canvas实现环形进度条的方法
2019/06/12 HTML / CSS
Haggar官网:美国男装品牌
2020/02/16 全球购物
数控专业大学生的自我鉴定
2013/11/13 职场文书
个人委托书格式
2014/04/04 职场文书
法院反腐倡廉心得体会
2014/09/09 职场文书
纪念九一八爱国演讲稿600字
2014/09/14 职场文书
党员教师四风问题对照检查材料
2014/09/26 职场文书
德能勤绩廉个人总结
2015/02/14 职场文书
2015年建党94周年演讲稿
2015/03/19 职场文书
民事起诉书范本
2015/05/19 职场文书
Python学习开发之图形用户界面详解
2021/08/23 Python