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进阶教程(第四课第一部分)
Apr 05 Javascript
手把手教你自己写一个js表单验证框架的方法
Sep 14 Javascript
jQuery实现的在线答题功能
Apr 12 Javascript
jQuery的基本概念与高级编程
May 14 Javascript
JS验证IP,子网掩码,网关和MAC的方法
Jul 02 Javascript
jquery彩色投票进度条简单实例演示
Jul 23 Javascript
基于JavaScript实现轮播图代码
Jul 14 Javascript
javaScript生成支持中文带logo的二维码(jquery.qrcode.js)
Jan 03 Javascript
JS实现图片点击后出现模态框效果
May 03 Javascript
微信小程序数据存储与取值详解
Jan 30 Javascript
vue 使用自定义指令实现表单校验的方法
Aug 28 Javascript
VUE中的v-if与v-show区别介绍
Mar 13 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
php实现删除空目录的方法
2015/03/16 PHP
php 升级到 5.3+ 后出现的一些错误,如 ereg(); ereg_replace(); 函数报错
2015/12/07 PHP
PHP中抽象类、接口的区别与选择分析
2016/03/29 PHP
php版微信返回用户text输入的方法
2016/11/14 PHP
thinkphp利用模型通用数据编辑添加和删除的实例代码
2016/11/20 PHP
CI框架实现创建自定义类库的方法
2018/12/25 PHP
NiftyCube——轻松实现圆角边框
2007/02/20 Javascript
javaScript call 函数的用法说明
2010/04/09 Javascript
一个简单的js渐显(fadeIn)渐隐(fadeOut)类
2010/06/19 Javascript
js实现在网页上简单显示时间的方法
2015/03/02 Javascript
jQuery Plupload上传插件的使用
2017/04/19 jQuery
JavaScript简单拖拽效果(1)
2017/05/17 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
2017/08/16 Javascript
微信小程序实现图片预览功能
2018/01/31 Javascript
create-react-app 修改为多入口编译的方法
2018/08/01 Javascript
JS封装的模仿qq右下角消息弹窗功能示例
2018/08/22 Javascript
ES6 更易于继承的类语法的使用
2019/02/11 Javascript
JavaScript前端开发时数值运算的小技巧
2020/07/28 Javascript
vue-cli脚手架的.babelrc文件用法说明
2020/09/11 Javascript
JavaScript实现单点登录的示例
2020/09/23 Javascript
[01:09:19]DOTA2-DPC中国联赛 正赛 VG vs Aster BO3 第二场 2月28日
2021/03/11 DOTA
Python查询Mysql时返回字典结构的代码
2012/06/18 Python
详解Python的Django框架中的中间件
2015/07/24 Python
python的random模块及加权随机算法的python实现方法
2017/01/04 Python
python 获取网页编码方式实现代码
2017/03/11 Python
Python3实现的简单三级菜单功能示例
2019/03/12 Python
Python图像处理库PIL中图像格式转换的实现
2020/02/26 Python
PyCharm 在Windows的有用快捷键详解
2020/04/07 Python
python:HDF和CSV存储优劣对比分析
2020/06/08 Python
Django返回HTML文件的实现方法
2020/09/17 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
1688平价精选商城:阿里集团旗下,工厂出厂价格直销
2017/04/24 全球购物
后勤主管岗位职责
2014/03/01 职场文书
事业单位考核材料
2014/05/21 职场文书
实验心得体会范文
2016/01/25 职场文书
使用python生成大量数据写入es数据库并查询操作(2)
2022/09/23 Python