JavaScript设计模式之责任链模式实例分析


Posted in Javascript onJanuary 16, 2019

本文实例讲述了JavaScript设计模式之责任链模式。分享给大家供大家参考,具体如下:

介绍

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

请求以后,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不知道哪一个对象将会处理它——也就是该请求有一个隐式的接受者(implicit receiver)。在运行时,任一候选者都可以响应相应的请求,候选者的数目是任意的,也可以在运行时刻决定哪些候选者参与到链中。

图解为:

JavaScript设计模式之责任链模式实例分析

正文

(1)由于类一般是与接口打交道的,为此我们先定义一个规范类中方法的接口,代码为

//定义一个静态方法来实现接口与实现类的直接检验
//静态方法不要写出Interface.prototype ,因为这是写到接口的原型链上的
//我们要把静态的函数直接写到类层次上
//定义一个接口类
var Interface=function (name,methods) {//name:接口名字
  if(arguments.length<2){
    alert("必须是两个参数")
  }
  this.name=name;
  this.methods=[];//定义一个空数组装载函数名
  for(var i=0;i<methods.length;i++){
    if(typeof methods[i]!="string"){
      alert("函数名必须是字符串类型");
    }else {
      this.methods.push( methods[i]);
    }
  }
};
Interface.ensureImplement=function (object) {
  if(arguments.length<2){
    throw new Error("参数必须不少于2个")
    return false;
  }
  for(var i=1;i<arguments.length;i++){
    var inter=arguments[i];
    //如果是接口就必须是Interface类型
    if(inter.constructor!=Interface){
      throw new Error("如果是接口类的话,就必须是Interface类型");
    }
    //判断接口中的方法是否全部实现
    //遍历函数集合分析
    for(var j=0;j<inter.methods.length;j++){
      var method=inter.methods[j];//接口中所有函数
      //object[method]传入的函数
      //最终是判断传入的函数是否与接口中所用函数匹配
      if(!object[method]||typeof object[method]!="function" ){//实现类中必须有方法名字与接口中所用方法名相同
        throw new Error("实现类中没有完全实现接口中的所有方法")
      }
    }
  }
}

(2)使用定义一个书店的接口

var bookShop=new Interface("bookShop",["addBook","findBook","showBooks"]);//书店接口

(3)定义一个书类

var Book=function (bNm,bName,bAuthor,bType) {
  this.bNm=bNm;
  this.bName=bName;
  this.bAuthor=bAuthor;
  this.bType=bType;
}

(4)书店类=书架+图书

1:在书店中添加书架和图书

var pcatBookShop=(function(){
 //书架
  var jsBooks = new Array();//js书架
  var cBooks = new Array();//c书架
  var javaBooks = new Array();//java书架
   //内部类1
  function AddJsBooks(book) {
    if(book.bType=="Js"){
      jsBooks.push(book);
    }else {
      AddJsBooks.successor(book);
    }
  }
  //内部类2
  function AddJavaBooks(book) {
    if(book.bType=="Java"){
      javaBooks.push(book);
    }else {
      AddJavaBooks.successor(book);
    }
  }
  //内部类3
  function AddCBooks(book) {
    if(book.bType=="C"){
      cBooks.push(book);
    }else {
      AddCBooks.successor(book);
    }
  }
})()

2:扩展设置责任链的方法(扩展在windows上)

//扩展window属性
window.setSuccessor=function (after,before) {
  after.successor=before;//引用的执行
}

3:设置责任链,将每个对象链接起来

//设置责任链-----串起来
setSuccessor(AddJsBooks,AddJavaBooks);
setSuccessor(AddJavaBooks,AddCBooks);

(5)查询图书的方法:通过图书编号和图书图书名称

 

/**********查询书籍************/
  var bookList = null;
  function FindBbn(keyword) {
    //链的头部来初始化参数
    if(!bookList){
      bookList=jsBooks.concat(cBooks).concat(javaBooks);
      var book = new Array();
      book=bookList.filter(function (book) {//对booklist进行过滤,过滤的条件为匿名函数
        if(book.bName.indexOf(keyword)!=-1){
             return true;
        }else {
          return false;
        }
      });
      //我要进行链式查询
      return book.concat(FindBbn.successor(keyword));
    }
  };
  function FindByName(keyword,book){
    var book = book;
    book = bookList.filter(function(book){
      if(book.bName.indexOf(keyword) != -1){
        return true;
      }else{
        return false;
      }
    });
    return book;
  }

注意,数组的filter方法扩展代码如下

Function.prototype.method=function (name,fn) {
  this.prototype[name]=fn;
  return this;
}
if(!Array.prototype.filter){
  Array.method("filter",function (fn,thisObj) {
    var scope=thisObj||window;
    var a=[];
    for(var i=0;i<this.length;i++){
      if(!fn.call(scope,this[i],i,this));{
        continue;
      }
      a.push(this[i]);
    }
    //返回过滤好数据
    return a;
  })
}

(6)规划责任链

setSuccessor(FindBbn,FindByName);

(7)真正的书店类(实现接口的类)

return function () {
    this.addBook=function (book) {
      if(book instanceof Book){
        AddJsBooks(book);//因为我知道谁是链的入口
      }
    };
    this.findBook=function (keyword) {
      return FindBbn(keyword);//游泳规划的责任链可以从头到尾的查询若,FindBbn没有则到FindByName中查询
    }
    this.showBooks=function () {
      document.write("JS类图书"+jsBooks.toSource()+"<br>");
      document.write("Java类图书"+javaBooks.toSource()+"<br>");
      document.write("C类图书"+cBooks.toSource()+"<br>");
      //自动生产----------
      document.write(cpoyStr(60,"-")+"<br>");
    }
  }

注意,在window上扩展一个可以自动生成“---------------”的方法

//扩展一个可以自动生产-----的方法
window.cpoyStr=function (num,str) {
  var newStr="";
  for(var i=0;i<num;i++){
   newStr+=str;
  }
  return newStr;
};

(8)使用书店

1:添加书

var pb = new pcatBookShop();
pb.addBook(new Book("00101","JAVA","JIM","JAVA"));
pb.addBook(new Book("00201","C#","world","C"));
pb.addBook(new Book("00202","C++/C","Hello","C"));
pb.addBook(new Book("00301","JAVASCRIPT","Good","JS"));

2:对书架上的书进行操作-----展示

//展示
pb.showBooks();
document.write(pb.findBook("C").toSource())

为此我们基本上完成了对责任链模式的使用方式的基本学习。

更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
js 禁止选择功能实现代码(兼容IE/Firefox)
Apr 23 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
Apr 25 Javascript
解析Jquery的LigerUI如何实现文件上传
Jul 09 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
Nov 08 Javascript
详细分析JavaScript函数定义
Jul 16 Javascript
js判断手机端(Android手机还是iPhone手机)
Jul 22 Javascript
js滚动条平滑移动示例代码
Mar 29 Javascript
JavaScript中如何使用cookie实现记住密码功能及cookie相关函数介绍
Nov 10 Javascript
用jquery的attr方法实现图片切换效果
Feb 05 Javascript
node实现生成带参数的小程序二维码并保存到本地功能示例
Dec 05 Javascript
单线程JavaScript实现异步过程详解
May 19 Javascript
Vue使用Element实现增删改查+打包的步骤
Nov 25 Vue.js
JavaScript设计模式之代理模式实例分析
Jan 16 #Javascript
vue-cli中vue本地实现跨域调试接口
Jan 16 #Javascript
vue element动态渲染、移除表单并添加验证的实现
Jan 16 #Javascript
深入koa-bodyparser原理解析
Jan 16 #Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 #jQuery
详解微信小程序之scroll-view的flex布局问题
Jan 16 #Javascript
vue开发环境配置跨域的方法步骤
Jan 16 #Javascript
You might like
PHP 编写的 25个游戏脚本
2009/05/11 PHP
php中判断数组是一维,二维,还是多维的解决方法
2013/05/04 PHP
WordPress中限制非管理员用户在文章后只能评论一次
2015/12/31 PHP
HTML5附件拖拽上传drop &amp; google.gears实现代码
2011/04/28 Javascript
使用Jquery打造最佳用户体验的登录页面的实现代码
2011/07/08 Javascript
推荐 21 款优秀的高性能 Node.js 开发框架
2014/08/18 Javascript
JS辨别访问浏览器判断是android还是ios系统
2014/08/19 Javascript
如何编写高质量JS代码(续)
2015/02/25 Javascript
JS实现间歇滚动的运动效果实例
2016/12/22 Javascript
原生js轮播(仿慕课网)
2017/02/15 Javascript
jQuery zTree树插件动态加载实例代码
2017/05/11 jQuery
强大的JavaScript响应式图表Chartist.js的使用
2017/09/13 Javascript
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
jquery之基本选择器practice(实例讲解)
2017/09/30 jQuery
vue+node实现图片上传及预览的示例方法
2018/11/22 Javascript
vue-cli3 DllPlugin 提取公用库的方法
2019/04/24 Javascript
[54:33]2018DOTA2亚洲邀请赛小组赛 A组加赛 Liquid vs Optic
2018/04/03 DOTA
mysql 之通过配置文件链接数据库
2017/08/12 Python
Python决策树分类算法学习
2017/12/22 Python
python打包生成的exe文件运行时提示缺少模块的解决方法
2018/10/31 Python
python调用matlab的m自定义函数方法
2019/02/18 Python
Django admin禁用编辑链接和添加删除操作详解
2019/11/15 Python
Python中logging日志库实例详解
2020/02/19 Python
英国Zoro工具:手动工具,电动工具和个人防护用品
2016/11/02 全球购物
英国鞋类及配饰零售商:Kurt Geiger
2017/02/04 全球购物
Clearly新西兰:购买眼镜、太阳镜和隐形眼镜
2018/04/26 全球购物
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
介绍一下Make? 为什么使用make
2013/12/08 面试题
会计专业毕业生求职信分享
2014/01/03 职场文书
摄影专业毕业生求职信
2014/03/13 职场文书
二年级小学生评语
2014/04/21 职场文书
劳资协议书范本
2014/04/23 职场文书
2014年信息技术工作总结
2014/12/16 职场文书
2015年医院护理部工作总结
2015/04/23 职场文书
优秀学生干部主要事迹材料
2015/11/04 职场文书
纪检部部长竞选稿
2015/11/21 职场文书