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 相关文章推荐
10个实用的脚本代码工具
May 04 Javascript
基于jquery实现状态限定编辑的代码
Feb 11 Javascript
javascript 使用 NodeList需要注意的问题
Mar 04 Javascript
JS测试显示屏分辨率以及屏幕尺寸的方法
Nov 22 Javascript
node.js中的path.basename方法使用说明
Dec 09 Javascript
JavaScript判断用户是否对表单进行了修改的方法
Mar 18 Javascript
AngularJs  Using $location详解及示例代码
Sep 02 Javascript
js控制一个按钮是否可点击(可使用)disabled的实例
Feb 14 Javascript
大白话讲解JavaScript的Promise
Apr 06 Javascript
Angularjs中的验证input输入框只能输入数字和小数点的写法(推荐)
Aug 16 Javascript
js打开word文档预览操作示例【不是下载】
May 23 Javascript
在Vue中使用icon 字体图标的方法
Jun 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
使用PHPMailer实现邮件发送代码分享
2014/10/23 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
2017/10/07 PHP
JavaScript窗口功能指南之在窗口中书写内容
2006/07/21 Javascript
JQuery 写的个性导航菜单
2009/12/24 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
基于jquery实现发送文章到手机的代码
2014/12/26 Javascript
JavaScript使用indexOf获得子字符串在字符串中位置的方法
2015/04/06 Javascript
AngularJS 实现按需异步加载实例代码
2015/10/18 Javascript
深入浅析JSON.parse()、JSON.stringify()和eval()的作用详解
2016/04/03 Javascript
Javascript json object 与string 相互转换的简单实现
2016/09/27 Javascript
JS函数修改html的元素内容,及修改属性内容的方法
2016/10/28 Javascript
你不知道的 javascript【推荐】
2017/01/08 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
2017/03/30 Javascript
node.js基于express使用websocket的方法
2017/11/09 Javascript
vue2.0 循环遍历加载不同图片的方法
2018/03/06 Javascript
vue中destroyed方法的使用说明
2020/07/21 Javascript
[08:17]Ti9 现场cosplay
2019/09/10 DOTA
Python中__new__与__init__方法的区别详解
2015/05/04 Python
python使用nntp读取新闻组内容的方法
2015/05/08 Python
Python自然语言处理 NLTK 库用法入门教程【经典】
2018/06/26 Python
Python设计模式之组合模式原理与用法实例分析
2019/01/11 Python
python3实现的zip格式压缩文件夹操作示例
2019/08/17 Python
TensorFlow内存管理bfc算法实例
2020/02/03 Python
Pytorch 使用opnecv读入图像由HWC转为BCHW格式方式
2020/06/02 Python
PyCharm2019 安装和配置教程详解附激活码
2020/07/31 Python
python3跳出一个循环的实例操作
2020/08/18 Python
如何查看浏览器对html5的支持情况
2020/12/15 HTML / CSS
海淘零差价,宝贝全球购: 宝贝格子
2016/08/24 全球购物
台湾母婴用品限时团购:妈咪爱
2018/08/03 全球购物
ShellScript面试题一则-ShellScript编程
2014/06/24 面试题
校园报刊亭的创业计划书
2014/01/02 职场文书
数控专业自荐书范文
2014/03/16 职场文书
警示教育活动总结
2014/05/05 职场文书
暑期教师培训方案
2014/06/07 职场文书
年底个人总结范文
2015/03/10 职场文书
Netty分布式客户端接入流程初始化源码分析
2022/03/25 Java/Android