学习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 相关文章推荐
js两行代码按指定格式输出日期时间
Oct 21 Javascript
js为鼠标添加右击事件防止默认的右击菜单弹出
Jul 29 Javascript
纯css+js写的一个简单的tab标签页带样式
Jan 28 Javascript
js中substring和substr的定义和用法
May 05 Javascript
js实现固定显示区域内自动缩放图片的方法
Jul 18 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
Apr 29 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
Jun 07 Javascript
微信小程序 教程之wxapp视图容器 swiper
Oct 19 Javascript
JavaScript实现自定义媒体播放器方法介绍
Jan 03 Javascript
js中变量的连续赋值(实例讲解)
Jul 08 Javascript
vue如何判断dom的class
Apr 26 Javascript
vue自定义右键菜单之全局实现
Apr 09 Vue.js
深入学习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
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
php中stdClass的用法分析
2015/02/27 PHP
php array_udiff_assoc 计算两个数组的差集实例
2016/11/12 PHP
PHP将数据导出Excel表中的实例(投机型)
2017/07/31 PHP
Laravel框架中缓存的使用方法分析
2019/09/06 PHP
JavaScript中String和StringBuffer的速度之争
2010/04/01 Javascript
jquery监控数据是否变化(修正版)
2011/04/12 Javascript
Prototype源码浅析 String部分(三)之HTML字符串处理
2012/01/15 Javascript
c#+jquery实现获取radio和checkbox的值
2020/09/12 Javascript
Javascript的闭包详解
2014/12/26 Javascript
JavaScript学习笔记整理_setTimeout的应用
2016/09/19 Javascript
JavaScript实现类似淘宝的购物车效果
2017/03/16 Javascript
微信小程序入门之广告条实现方法示例
2018/12/05 Javascript
vue+element表格导出为Excel文件
2019/09/26 Javascript
React Native登录之指纹登录篇的示例代码
2020/11/03 Javascript
python简单实现基于SSL的IRC bot实例
2015/06/15 Python
django创建自定义模板处理器的实例详解
2017/08/14 Python
IntelliJ IDEA安装运行python插件方法
2018/12/10 Python
Python 正则表达式 re.match/re.search/re.sub的使用解析
2019/07/22 Python
python 如何利用argparse解析命令行参数
2020/09/11 Python
pycharm 实现复制一行的快捷键
2021/01/15 Python
纯CSS3实现运行时钟的示例代码
2021/01/25 HTML / CSS
localstorage和sessionstorage使用记录(推荐)
2017/05/23 HTML / CSS
基于HTML5 Canvas的3D动态Chart图表的示例
2017/11/02 HTML / CSS
京东奢侈品:全球奢侈品牌
2018/03/17 全球购物
Lyle & Scott苏格兰金鹰官网:英国皇室御用品牌
2018/05/09 全球购物
亚洲领先的旅游体验市场:Voyagin
2019/11/23 全球购物
简述进程的启动、终止的方式以及如何进行进程的查看
2013/07/12 面试题
电气工程及其自动化自我评价四篇
2013/09/24 职场文书
招商经理岗位职责
2013/11/16 职场文书
校园招聘策划书
2014/01/09 职场文书
运动会通讯稿50字
2014/01/30 职场文书
幼儿园大班教师个人总结
2015/02/05 职场文书
opencv 分类白天与夜景视频的方法
2021/06/05 Python
JavaScript前端面试扁平数据转tree与tree数据扁平化
2022/06/14 Javascript
MySQL提升大量数据查询效率的优化神器
2022/07/07 MySQL