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 相关文章推荐
jQuery中animate用法实例分析
Mar 09 Javascript
jQuery插件之jQuery.Form.js用法实例分析(附demo示例源码)
Jan 04 Javascript
jQuery改变form表单的action,并进行提交的实现代码
May 25 Javascript
jquery判断对象是否为空并遍历对象的简单实例
Jul 26 Javascript
Vue获取DOM元素样式和样式更改示例
Mar 07 Javascript
微信小程序实现点击返回顶层的方法
Jul 12 Javascript
javascript Function函数理解与实战
Dec 01 Javascript
浅谈AngularJS中$http服务的简单用法
May 15 Javascript
vue-i18n结合Element-ui的配置方法
May 20 Javascript
jquery获取并修改触发事件的DOM元素示例【基于target 属性】
Oct 10 jQuery
Vue组件通信入门之Provide和Inject机制
Dec 29 Javascript
在vant 中使用cell组件 定义图标该图片和位置操作
Nov 02 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
FCKeditor添加自定义按钮
2008/03/27 PHP
php mailer类调用远程SMTP服务器发送邮件实现方法
2016/03/04 PHP
JQuery操作元素的css样式
2015/03/09 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
JS常用字符串方法(推荐)
2021/01/15 Javascript
Vue 过渡(动画)transition组件案例详解
2017/01/22 Javascript
JavaScript实现翻页功能(附效果图)
2017/02/16 Javascript
详解Vue中状态管理Vuex
2017/05/11 Javascript
使用nvm管理不同版本的node与npm的方法
2017/10/31 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
2018/09/07 Javascript
JS实现查找数组中对象的属性值是否存在示例
2019/05/24 Javascript
vue-router路由模式详解(小结)
2019/08/26 Javascript
jQuery 移除事件的方法
2020/06/20 jQuery
js实现鼠标滑动到某个div禁止滚动
2020/09/17 Javascript
vue 获取url里参数的两种方法小结
2020/11/12 Javascript
JavaScript事件概念详解(区分静态注册和动态注册)
2021/02/05 Javascript
[01:06:54]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第一场 1月24日
2021/03/11 DOTA
python网页请求urllib2模块简单封装代码
2014/02/07 Python
用python + hadoop streaming 分布式编程(一) -- 原理介绍,样例程序与本地调试
2014/07/14 Python
Python实现查找系统盘中需要找的字符
2015/07/14 Python
Python 读取 YUV(NV12) 视频文件实例
2019/12/09 Python
Python文件操作函数用法实例详解
2019/12/24 Python
解决Django提交表单报错:CSRF token missing or incorrect的问题
2020/03/13 Python
详解PyQt5信号与槽的几种高级玩法
2020/03/24 Python
Python多线程的退出控制实现
2020/08/10 Python
Python如何急速下载第三方库详解
2020/11/02 Python
matplotlib相关系统目录获取方式小结
2021/02/03 Python
亚历山大·王官网:Alexander Wang
2017/06/23 全球购物
几道数据库的概念性面试题
2014/05/30 面试题
酒店副总经理岗位职责范本
2014/02/04 职场文书
课程设计的心得体会
2014/09/03 职场文书
预备党员转正思想汇报
2014/09/26 职场文书
使用Golang的channel交叉打印两个数组的操作
2021/04/29 Golang
Win11怎么跳过联网验机 ?Win11跳过联网验机激活教程
2022/04/05 数码科技
Java 超详细讲解hashCode方法
2022/04/07 Java/Android