学习JavaScript设计模式之责任链模式


Posted in Javascript onJanuary 18, 2016

一、定义

责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

二、示例

  • 假设这么一个场景:
  • 我们负责一个售卖手机的电商网站,经过分别缴纳500元定金和200元定金的两轮预定后,到了正式购买阶段。针对预定用户实行优惠,支付过500元定金的用户会收到100元的商城优惠券,支付过200元定金的用户会收到50元的商城优惠券,没有支付定金的用户归为普通购买,且在库存有限的情况下不一定保证买到。
/* 传统方式实现 */
// orderType:[1:500, 2:200, 3:普通],isPaid:true/false,stock:库存量
var order = function(orderType, isPaid, stock) {
  if(orderType === 1) {
    if(isPaid) {
      console.log("500元定金预购,得到100优惠券");
    } else {
      if(stock > 0) {
        console.log("普通购买,无优惠券");
      }else {
        console.log("库存不足");
      }
    }
  }else if(orderType === 2) {
    if(isPaid) {
      console.log("200元定金预购,得到50优惠券");
    } else {
      if(stock > 0) {
        console.log("普通购买,无优惠券");
      }else {
        console.log("库存不足");
      }
    }
  }else if(orderType === 2) {
    if(stock > 0) {
      console.log("普通购买,无优惠券");
    }else {
      console.log("库存不足");
    }
  }
}

order(1, true, 500);

/*职责链 */
var order500 = function(orderType, isPaid, stock) {
  if(orderType === 1 && isPaid === true) {
    console.log("500元定金预购,得到100优惠券");
  }else {
    return "nextSuccessor";
  }
};

var order200 = function(orderType, isPaid, stock) {
  if(orderType === 2 && isPaid === true) {
    console.log("200元定金预购,得到50优惠券");
  }else {
    return "nextSuccessor";
  }
};

var orderNormal = function(orderType, isPaid, stock) {
  if(stock > 0) {
    console.log("普通购买,无优惠券");
  }else {
    console.log("库存不足");
  }
};

Function.prototype.after = function(fn) {
  var self = this;
  return function() {
    var ret = self.apply(this, arguments);
    if(ret === "nextSuccessor") {
      return fn.apply(this, arguments);
    }
    return ret;
  };
}

var order = order500.after(order200).after(orderNormal);
order(1, true, 10);

优点:解耦了请求发送者和N个接受者之间的复杂关系。
弊端:不能保证某个请求一定会被链中的节点处理。

三、示例:文件上传对象

示例2:用责任链模式获取文件上传对象
PS:对比《学习JavaScript设计模式之迭代器模式》

function getActiveUploadObj() {
  try{
    return new ActiveObject("TXFTNActiveX.FTNUpload"); // IE上传控件
  }catch(e) {
    return "nextSuccessor";
  }
}

function getFlashUploadObj() {
  if(supportFlash().f === 1) {  // supportFlash见《JavaScript设计模式--迭代器模式》
    var str = '<object type="application/x-shockwave-flash"></object>';
    return $(str).appendTo($("body"));
  }
  return "nextSuccessor";
}

function getFormUploadObj() {
  var str = '<input name="file" type="file" class="ui-file" />';
  return $(str).appendTo($("body"));
}

var getUploadObj = getActiveUploadObj.after(getFlashUploadObj).after(getFormUploadObj);

console.log(getUploadObj());

无论是作用域链、原型链、还是DOM节点中的事件冒泡,我们都能从中找到职责链的影子。

以上就是本文的全部内容,希望本文所述对大家学习javascript程序设计有所帮助。。

Javascript 相关文章推荐
23个超流行的jQuery相册插件整理分享
Apr 25 Javascript
JQury slideToggle闪烁问题及解决办法
Jul 05 Javascript
用JSON做数据传输格式中的一些问题总结
Dec 21 Javascript
jquery 获取表单元素里面的值示例代码
Jul 28 Javascript
js冒泡法和数组转换成字符串示例代码
Aug 14 Javascript
jquery+ajax实现省市区三级联动效果简单示例
Jan 04 Javascript
BootStrap模态框不垂直居中的解决方法
Oct 19 Javascript
Javascript中prototype与__proto__的关系详解
Mar 11 Javascript
JS实现点击发送验证码 xx秒后重新发送功能
Jul 30 Javascript
手把手15分钟搭一个企业级脚手架
Sep 16 Javascript
VUE解决 v-html不能触发点击事件的问题
Oct 28 Javascript
vue addRoutes路由动态加载操作
Aug 04 Javascript
深入学习jQuery Validate表单验证(二)
Jan 18 #Javascript
深入学习jQuery Validate表单验证
Jan 18 #Javascript
jQuery Validate表单验证插件 添加class属性形式的校验
Jan 18 #Javascript
图片旋转、鼠标滚轮缩放、镜像、切换图片js代码
Dec 13 #Javascript
理解JavaScript中Promise的使用
Jan 18 #Javascript
你不知道的高性能JAVASCRIPT
Jan 18 #Javascript
Ionic实现仿通讯录点击滑动及$ionicscrolldelegate使用分析
Jan 18 #Javascript
You might like
PHP经典的给图片加水印程序
2006/12/06 PHP
页面利用渐进式JPEG来提升用户体验度
2014/12/01 PHP
PHP中is_file()函数使用指南
2015/05/08 PHP
PHP实现通过get方式识别用户发送邮件的方法
2015/07/16 PHP
Nigma vs Alliance BO5 第四场2.14
2021/03/10 DOTA
Javascript &amp; DHTML 实例编程(教程)(三)初级实例篇1—上传文件控件实例
2007/06/02 Javascript
Jquery插件之多图片异步上传
2010/10/20 Javascript
基于MooTools的很有创意的滚动条时钟动画
2010/11/14 Javascript
Js实现双击鼠标自动滚动屏幕的示例代码
2013/12/14 Javascript
js判断undefined类型示例代码
2014/02/10 Javascript
js操作模态窗口及父子窗口间相互传值示例
2014/06/09 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
基于BootStrap Metronic开发框架经验小结【一】框架总览及菜单模块的处理
2016/05/12 Javascript
JavaScript生成图形验证码
2020/08/24 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
Vue的elementUI实现自定义主题方法
2018/02/23 Javascript
vue中input的v-model清空操作
2019/09/06 Javascript
[58:09]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第三场 6.2
2018/06/03 DOTA
Python FTP操作类代码分享
2014/05/13 Python
python实现自动发送邮件
2018/06/20 Python
django解决跨域请求的问题详解
2019/01/20 Python
Python实现一个数组除以一个数的例子
2019/07/20 Python
记一次pyinstaller打包pygame项目为exe的过程(带图片)
2020/03/02 Python
python中安装django模块的方法
2020/03/12 Python
Python基于paramunittest模块实现excl参数化
2020/04/26 Python
python如何编写类似nmap的扫描工具
2020/11/06 Python
带有css3动画效果的兼容多浏览器简单导航条示例
2014/01/26 HTML / CSS
CSS3点击按钮实现背景渐变动画效果
2016/10/19 HTML / CSS
基本款天堂:Everlane
2017/05/13 全球购物
de Bijenkorf比利时官网:荷兰最知名的百货商店
2017/06/29 全球购物
Fanatics英国官网:美国体育电商
2018/11/06 全球购物
德国婴儿服装和婴儿用品购买网站:Baby Sweets
2019/12/08 全球购物
Linux内核产生并发的原因
2012/07/13 面试题
三八节活动主持词
2015/07/04 职场文书
2015重阳节座谈会主持词
2015/07/30 职场文书
详解JS数组方法
2021/11/20 Javascript