JavaScript职责链模式概述

一、概述

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

貌似和数据结构中的链表一样。

但,不要搞混了,职责链可不等于链表哦,因为职责链可以在任何一个节点开始往下查找,而链表,则必须从头结点开始往下查找。

比如,DOM事件机制中的冒泡事件就属于职责链,而捕获事件则属于链表。

二、利用职责链模拟冒泡

假设我们有三个对象:li、ul、div,三者关系图如下:

比如,当我们触发li对象时,如果li没有阻止冒泡,那么将会传递给ul对象,到了ul,如果没有阻止冒泡,则会传递给div对象(假设这里div为根节点)。同理,ul、div。

看到这儿,很清楚适合用职责链模式,编写这样的需求。

但,怎么使用JavaScript实现职责链模式呢?

如下,我们可以通过原型链的方式构建基本架构:

function CreateDOM(obj){
  this.next = obj || null;
};
CreateDOM.prototype = {
  handle: function(){
    if(this.next){
      this.next.handle();
    }
  }
};

每当我们利用CreateDOM构造函数,创建一个对象时,就将与之关联的对象传递进去(嗯,这样很链表)。

然后,当我们触发某个对象,执行handle方法时,就可以沿着这条链,走下去了。

但,需注意,当某个对象的handle属性覆盖了原型链中的handle时,怎么继续往下传呢?

利用CreateDOM.prototype.handle.call(this);就好了。

So,实现li、ul和div代码如下:

var li = null,
  ul = null,
  div = null;
div = new CreateDOM();
div.handle = function(stopBubble){
  console.log('DIV');
  if(stopBubble){
    return;
  }else{
    CreateDOM.prototype.handle.call(this);
  }
};
ul = new CreateDOM(div);
ul.handle = function(stopBubble){
  console.log('UL');
  if(stopBubble){
    return;
  }else{
    CreateDOM.prototype.handle.call(this);
  }
};
li = new CreateDOM(ul);
li.handle = function(stopBubble){
  console.log('LI');
  if(stopBubble){
    return;
  }else{
    CreateDOM.prototype.handle.call(this);
  }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 轻松掌握JavaScript装饰者模式

    在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但继承的方式会带来问题:当父类改变时,他的所有子类都将随之改变. 当JavaScript脚本运行时,在一个对象中(或他的原型上)增加行为会影响该对象的所有实例, 装饰者是一种实现继承的替代方案,它通过重载方法的形式添加新功能,该模式可以在被装饰者前面(before)或者后面(after)加上自己的行为以达到特定的目的. 装饰者模式是为已有功能动态地添加更多功能的一种方式,把每个要装饰的功能放在单独的函数里,然后用该函数包装所要装饰的已有函

  • 轻松掌握JavaScript中介者模式

    中介者模式的作用就是解除对象与对象之间的紧耦合关系,它也称'调停者'.所有的对象都通过中介者对象来通信,而不是相互引用,所以当一个对象发生改变时,只需要通知中介者即可. 如:机场的指挥塔,每架飞机都只需要和指挥塔通信即可,指挥塔知道每架飞机的飞行状况,可以安排所有起降时间,调整航线等 中介者模式符合迪米特法则,即最少知识原则,指一个对象应该尽可能少地了解另外的对象.如果对象之间的耦合性太高,则改变一个对象,会牵动很多对象,难于维护.当对象耦合很紧时,要修改一个对象而不影响其它的对象是很困难的.

  • 轻松掌握JavaScript享元模式

    在JavaScript中,浏览器特别是移动端的浏览器分配的内存很有限,如何节省内存就成了一件非常有意义的事情.节省内存的一个有效方法是减少对象的数量. 享元模式(Flyweight),运行共享技术有效地支持大量细粒度的对象,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类). 享元模式可以避免大量非常相似类的开销,在程序设计中,有时需要生产大量细粒度的类实例来表示数据,如果能发现这些实例除了几个参数以外,开销基本相同的话,就可以大幅度较少需要实例化的类的数量.如果能把那些参

  • 轻松掌握JavaScript策略模式

    定义:定义一系列的算法,把它们一个个封装成函数,也可把它们作为属性统一封装进一个对象,然后再定义一个方法,该方法可根据参数自动选择执行对应的算法. 一般用于在实现一个功能时,有很多个方案可选择的情况. 例子1:根据员工薪水salary.绩效等级S.A.B.C,来计算年终奖 //封装了所有算法的策略对象 var strategies = { 'S': function(salary){ return salary*4; }, 'A': function(salary){ return salary

  • 轻松掌握JavaScript代理模式

    在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就多,它把这些职责耦合到了一起,这种耦合会导致程序难于维护和重构. 这时候,我们可以把该对象(本体)的其中一部分职责分离出来给一些第三方对象去做,本体只管自己的一些核心职责,这些第三方对象就称作代理.代理对象可以作为对象(也叫"真正的主体")的保护者,让真正的主体对象做尽量少的工作.在代理设计模式中,一个对象充当了另一个对

  • C#职责链模式实例详解

    本文实例讲述了C#职责链模式.分享给大家供大家参考.具体如下: ConcreteHandler1.cs如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { public class ConcreteHandler1:Handler { public override void HandRequest(int

  • 深入理解JavaScript系列(38):设计模式之职责链模式详解

    介绍 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止. 也就是说,请求以后,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者.提交请求的对象并不明确知道哪一个对象将会处理它--也就是该请求有一个隐式的接受者(implicit receiver).根据运行时刻,任一候选者都可以响应相应的请求,候选者的数目是任意

  • C++设计模式之职责链模式

    前言 最近心情很差,因为生活,因为工作:所以想请几天假去丽江玩玩.就向项目经理提交了休假申请,我的项目经理向项目主管提交了我的休假申请,项目主管向部门经理提交了我的休假申请:最后,部门经理同意了我的休假申请.是的,一个简单的休假申请,需要这么复杂的流程,这也是一个公司保证它正常运行的必要.如果部门经理休假了,那么我的休假申请由谁审批呢?这个时候由项目主管代替部门经理进行审批.一个休假申请的审批制度有着严格的要求.而在处理这个请假审批时,各个人员就好比在一条链上的节点,我不知道我的请求由谁审批,但

  • 轻松掌握JavaScript单例模式

    定义:保证一个对象(类)仅有一个实例,并提供一个访问它的全局访问点: 实现原理:利用闭包来保持对一个局部变量的引用,这个变量保存着首次创建的唯一的实例;  主要用于:全局缓存.登录浮窗等只需要唯一一个实例的时候: 一. 为一个非单例模式对象(如:Demo)实现单例模式的方法:  给Demo添加一个静态方法来实现单例: Demo.getSingle = (function(){ var demo = null; return function(name){ if(!demo){ demo = ne

  • php设计模式 Chain Of Responsibility (职责链模式)

    复制代码 代码如下: <?php /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * */ abstract class Handler { protected $_handler = null; public function setSuccessor($handler) { $this->_handler = $handler; } abstract functio

随机推荐