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 自动完成 AutoComplete(Ajax 查询)
Jul 07 Javascript
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
Feb 04 Javascript
IE6、IE7中setAttribute不支持class/for/rowspan/colspan等属性
Aug 28 Javascript
JavaScript加入收藏夹功能(兼容IE、firefox、chrome)
May 05 Javascript
JavaScript中利用Array和Object实现Map的方法
Jul 27 Javascript
Angular路由简单学习
Dec 26 Javascript
vue.js将时间戳转化为日期格式的实现代码
Jun 05 Javascript
JS 正则表达式验证密码、邮箱格式的实例代码
Oct 28 Javascript
js中对象和面向对象与Json介绍
Jan 21 Javascript
基于vue实现web端超大数据量表格的卡顿解决
Apr 02 Javascript
JS实现导航栏楼层特效
Jan 01 Javascript
uniapp,微信小程序中使用 MQTT的问题
Jul 11 Javascript
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作为网站开发语言的原因分享
2012/01/03 PHP
PHP面向对象——访问修饰符介绍
2012/11/08 PHP
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
php基于 swoole 实现的异步处理任务功能示例
2019/08/13 PHP
写的htc的数据表格
2007/01/20 Javascript
excel操作之Add Data to a Spreadsheet Cell
2007/06/12 Javascript
JavaScript入门学习书籍推荐
2008/06/12 Javascript
使用jQuery全局事件ajaxStart为特定请求实现提示效果的代码
2010/12/30 Javascript
jQuery设置div一直在页面顶部显示的方法
2013/10/24 Javascript
jquery $.fn $.fx是什么意思有什么用
2013/11/04 Javascript
学习JavaScript设计模式之观察者模式
2020/04/22 Javascript
JS请求servlet功能示例
2017/06/01 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
2017/07/07 Javascript
解决IE7中使用jQuery动态操作name问题
2017/08/28 jQuery
基于复选框demo(分享)
2017/09/27 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
2018/01/18 Javascript
AngularJS 将再发布一个重要版本 然后进入长期支持阶段
2018/01/31 Javascript
jQuery Ajax async=&gt;false异步改为同步时,解决导致浏览器假死的问题
2019/07/22 jQuery
ES2020 新特性(种草)
2020/01/12 Javascript
python实现网页链接提取的方法分享
2014/02/25 Python
Python获取电脑硬件信息及状态的实现方法
2014/08/29 Python
python通过正则查找微博@(at)用户的方法
2015/03/13 Python
python实现登陆知乎获得个人收藏并保存为word文件
2015/03/16 Python
Python实现爬取逐浪小说的方法
2015/07/07 Python
详解python算法之冒泡排序
2019/03/05 Python
由Python编写的MySQL管理工具代码实例
2019/04/09 Python
python 中的列表生成式、生成器表达式、模块导入
2019/06/19 Python
出纳员岗位职责风险
2014/03/06 职场文书
课前三分钟演讲稿
2014/04/24 职场文书
学校标语大全
2014/06/19 职场文书
人事专员岗位说明书
2014/07/29 职场文书
怒海潜将观后感
2015/06/11 职场文书
高三教师工作总结2015
2015/07/21 职场文书
六一儿童节致辞
2015/07/31 职场文书
2016形势与政策学习心得体会
2016/01/12 职场文书
导游词之青岛太清宫
2019/12/13 职场文书