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 相关文章推荐
建立良好体验度的Web注册系统ajax
Jul 09 Javascript
基于javascript实现仿百度输入框自动匹配功能
Jan 03 Javascript
sso跨域写cookie的一段js脚本(推荐)
May 25 Javascript
简单的Vue异步组件实例Demo
Dec 27 Javascript
详解给Vue2路由导航钩子和axios拦截器做个封装
Apr 10 Javascript
4个顶级JavaScript高级文本编辑器
Oct 10 Javascript
js实现简单模态框实例
Nov 16 Javascript
移动端滑动切换组件封装 vue-swiper-router实例详解
Nov 25 Javascript
基于Koa2写个脚手架模拟接口服务的方法
Nov 27 Javascript
基于Fixed定位的框选功能的实现代码
May 13 Javascript
jQuery高级编程之js对象、json与ajax用法实例分析
Nov 01 jQuery
javascript设计模式 ? 模板方法模式原理与用法实例分析
Apr 23 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
Session保存到数据库的php类分享
2011/10/24 PHP
解析dedecms空间迁移步骤详解
2013/05/15 PHP
php上传文件中文文件名乱码的解决方法
2013/11/01 PHP
PHP基于堆栈实现的高级计算器功能示例
2017/09/15 PHP
用JavaScript显示随机图像或引用
2009/04/21 Javascript
JavaScript实现拼音排序的方法
2012/11/20 Javascript
jquery插件如何使用 jQuery操作Cookie插件使用介绍
2012/12/15 Javascript
javascript Array.prototype.slice的使用示例
2013/11/14 Javascript
JavaScript实现的购物车效果可以运用在好多地方
2014/05/09 Javascript
JavaScript中Function详解
2015/02/27 Javascript
在AngularJS中使用AJAX的方法
2015/06/17 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
详解JavaScript函数
2015/12/01 Javascript
javascript实现checkbox复选框实例代码
2016/01/10 Javascript
JS设置cookie、读取cookie
2016/02/24 Javascript
javascript验证内容为数字以及长度为10的简单实例
2016/08/20 Javascript
使用vue编写一个点击数字计时小游戏
2016/08/31 Javascript
前端设计师们最常用的JS代码汇总
2016/09/25 Javascript
什么是JavaScript中的结果值?
2016/10/08 Javascript
Async Validator 异步验证使用说明
2017/07/03 Javascript
如何在Vue.js中实现标签页组件详解
2019/01/02 Javascript
JavaScript中break、continue和return的用法区别实例分析
2020/03/02 Javascript
24个ES6方法解决JS实际开发问题(小结)
2020/05/31 Javascript
Python装饰器使用示例及实际应用例子
2015/03/06 Python
将Python的Django框架与认证系统整合的方法
2015/07/24 Python
Anaconda 离线安装 python 包的操作方法
2018/06/11 Python
对python中dict和json的区别详解
2018/12/18 Python
pygame实现打字游戏
2021/02/19 Python
python 实现多维数组(array)排序
2020/02/28 Python
Django日志及中间件模块应用案例
2020/09/10 Python
日本高岛屋百货购物网站:TAKASHIMAYA
2019/03/24 全球购物
Europcar澳大利亚官网:全球汽车租赁领域的领导者
2019/03/24 全球购物
德国大型和小型家用电器网上商店:Energeto
2019/05/15 全球购物
自我鉴定四大框架
2014/01/17 职场文书
教师个人总结范文
2015/02/11 职场文书
Python selenium绕过webdriver监测执行javascript
2022/04/12 Python