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.validate使用攻略 第五步 正则验证
Jul 01 Javascript
JavaScript给url网址进行encode编码的方法
Mar 18 Javascript
浅析AngularJs HTTP响应拦截器
Dec 28 Javascript
分享jQuery网页元素拖拽插件
Dec 01 Javascript
深入浅析JavaScript中的Function类型
Jul 09 Javascript
微信小程序 设置启动页面的两种方法
Mar 09 Javascript
BootStrap表单控件之文本域textarea
May 23 Javascript
详谈js对url进行编码和解码(三种方式的区别)
Aug 16 Javascript
vue文件树组件使用详解
Mar 29 Javascript
关于element-ui表单中限制输入纯数字的解决方式
Sep 08 Javascript
Openlayers测量距离与面积的实现方法
Sep 25 Javascript
TypeScript魔法堂之枚举的超实用手册
Oct 29 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 执行系统外部命令 system() exec() passthru()
2009/08/11 PHP
CI框架网页缓存简单用法分析
2018/12/26 PHP
Html中JS脚本执行顺序简单举例说明
2010/06/19 Javascript
JavaScript日历实现代码
2010/09/12 Javascript
删除select中所有option选项jquery代码
2013/08/12 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
基于javascript实现图片预加载
2016/01/05 Javascript
Angular实现form自动布局
2016/01/28 Javascript
jQuery Mobile 和 Kendo UI 的比较
2016/05/05 Javascript
jQuery弹出层插件popShow用法示例
2017/01/23 Javascript
快速解决处理后台返回json数据格式的问题
2018/08/07 Javascript
Node.js中的不安全跳转如何防御详解
2018/10/21 Javascript
基于jQuery实现可编辑的表格
2019/12/11 jQuery
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
Python异常学习笔记
2015/02/03 Python
Python的CGIHTTPServer交互实现详解
2018/02/08 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
Selenium基于PIL实现拼接滚动截图
2020/04/10 Python
Tensorflow中的降维函数tf.reduce_*使用总结
2020/04/20 Python
pip安装提示Twisted错误问题(Python3.6.4安装Twisted错误)
2020/05/09 Python
Python爬虫+Tkinter制作一个翻译软件的示例
2021/02/20 Python
市场营销专业毕业生自荐信
2013/11/02 职场文书
应聘自荐信
2013/12/14 职场文书
会计专业大学生职业生涯规划书
2014/02/11 职场文书
护理专科自荐书范文
2014/02/18 职场文书
寄语是什么意思
2014/04/10 职场文书
计算机求职自荐信范文
2014/04/19 职场文书
好的促销活动方案
2014/08/21 职场文书
初中同学会活动方案
2014/08/22 职场文书
新闻学专业职业生涯规划范文:我的人生我做主
2014/09/12 职场文书
纪念一二九运动演讲稿
2014/09/16 职场文书
2014年党小组工作总结
2014/12/20 职场文书
从严治党主题教育活动总结
2015/05/07 职场文书
活动总结模板大全
2015/05/11 职场文书
申论不会写怎么办?教您掌握这6点思维和原则
2019/07/17 职场文书
python实现一个简单的贪吃蛇游戏附代码
2022/06/28 Python