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 相关文章推荐
js取滚动条的尺寸的函数代码
Nov 30 Javascript
使用jquery动态加载javascript以减少服务器压力
Oct 29 Javascript
js实现超简单的展开、折叠目录代码
Aug 28 Javascript
有关文件上传 非ajax提交 得到后台数据问题
Oct 12 Javascript
基于jQuery实现左侧菜单栏可折叠功能
Dec 27 Javascript
jQuery编写设置和获取颜色的插件
Jan 09 Javascript
js以及jquery实现手风琴效果
Apr 17 Javascript
vue.js项目中实用的小技巧汇总
Nov 29 Javascript
微信小程序表单验证form提交错误提示效果
Jun 19 Javascript
详解Nuxt.js中使用Element-UI填坑
Sep 06 Javascript
nuxt静态部署打包相对路径操作
Nov 06 Javascript
vue实力踩坑之push当前页无效
Apr 10 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 第三节 变量介绍
2012/04/28 PHP
php实现QQ空间获取当前用户的用户名并生成图片
2015/07/25 PHP
Yii中表单用法实例详解
2016/01/05 PHP
关于PhpStorm设置点击编辑文件自动定位源文件的实现方式
2020/12/30 PHP
用jscript实现新建word文档
2007/06/15 Javascript
一些经常会用到的Javascript检测函数
2010/05/31 Javascript
js hover 定时器(实例代码)
2013/11/12 Javascript
浅谈javascript对象模型和function对象
2014/12/26 Javascript
浅谈node.js中async异步编程
2015/10/22 Javascript
JavaScript实现Java中Map容器的方法
2016/10/09 Javascript
浅谈js的异步执行
2016/10/18 Javascript
NodeJS中的MongoDB快速入门详细教程
2016/11/11 NodeJs
vue3.0中使用element的完整步骤
2021/03/04 Vue.js
python中Genarator函数用法分析
2015/04/08 Python
讲解Python中for循环下的索引变量的作用域
2015/04/15 Python
介绍Python中的fabs()方法的使用
2015/05/14 Python
Django返回json数据用法示例
2016/09/18 Python
用pickle存储Python的原生对象方法
2017/04/28 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
Python实现PS滤镜功能之波浪特效示例
2018/01/26 Python
Python函数和模块的使用总结
2019/05/20 Python
python读取文件指定行内容实例讲解
2020/03/02 Python
python打包多类型文件的操作方法
2020/09/21 Python
python 爬取免费简历模板网站的示例
2020/09/27 Python
如何利用python正则表达式匹配版本信息
2020/12/09 Python
使用CSS3 制作一个material-design 风格登录界面实例
2016/12/12 HTML / CSS
计算机应用专业毕业生求职信
2013/10/24 职场文书
机械化及自动化毕业生的自我评价分享
2013/11/06 职场文书
回门宴父母答谢词
2014/01/26 职场文书
测控技术自荐信
2014/06/05 职场文书
2014国庆节标语口号
2014/09/19 职场文书
2016年圣诞节义工活动总结
2016/04/01 职场文书
Python基础之操作MySQL数据库
2021/05/06 Python
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技
Java生成日期时间存入Mysql数据库的实现方法
2022/03/03 Java/Android