欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

javascript设计模式 – 职责链模式原理与用法实例分析

程序员文章站 2024-01-02 12:00:04
本文实例讲述了javascript设计模式 – 职责链模式原理与用法。分享给大家供大家参考,具体如下:介绍:很多情况下,在一个软件系统中可以处理某个请求的对象不止一个。例如一个网络请求过来,需要有对象...

本文实例讲述了javascript设计模式 – 职责链模式原理与用法。分享给大家供大家参考,具体如下:

介绍:很多情况下,在一个软件系统中可以处理某个请求的对象不止一个。例如一个网络请求过来,需要有对象去解析request body,需要有对象去解析请求头,还需要有对象去对执行对应controller。请求一层层传递,让每一个对象都基于请求完成自己的任务,然后将请求传递给下一个处理程序。是不是感觉有点中间件的感觉。

定义:职责链就是避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求。将这些对象连成一条链,并沿着链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

场景:我们继续画圆,我们准备了两组示例:

示例:

var circle = function(){
  this.radius = 0;
 
  this.drawbyradius = function(radius){
    if(radius < 5){
      this.drawverysmalcircle();
    }else if(radius < 10){
      this.drawsmalcircle();
    }else if(radius < 15){
      this.drawmediumcircle();
    }else if(radius < 20){
      this.drawbigcircle();
    }else{
      this.drawverybigcircle();
    }
  }
 
  this.drawverysmalcircle = function(){
    console.log('画一个超小的圆( 5以下 )');
  }
  this.drawsmalcircle = function(){
    console.log('画一个小圆( 5-10 )');
  }
  this.drawmediumcircle = function(){
    console.log('画一个中圆 ( 10-15 )');
  }
  this.drawbigcircle = function(){
    console.log('画一个大圆 ( 15-20 )');
  }
  this.drawverybigcircle = function(){
    console.log('画一个超大的圆 ( 20以上 )');
  }
}
 
var circle = new circle();
circle.drawbyradius(30);
//画一个超大的圆 ( 20以上 )

观察上面的代码,这是很常见的逻辑,通过参数来决定执行哪个方法。首先drawbyradius方法职责过重,其次这样的方式在修改,新增时需要修改源代码,不符合开关原则。

我们使用职责链模式重写下:

var drawsmalcircle = function(min,max){
  this.max = max;
  this.min = min;
  this.nextcircle;
  this.setnextdraw = function(circle){
    this.nextcircle = circle;
  }
  this.draw = function(radius){
    console.log('执行:drawsmalcircle');
    if(this.min < radius && radius < this.max){
      console.log('画一个小圆( 10以下 )');
    }
    if(this.nextcircle){
      this.nextcircle.draw(radius)
    }
  }
}
 
var drawmediumcircle = function(min,max){
  this.max = max;
  this.min = min;
  this.nextcircle;
  this.setnextdraw = function(circle){
    this.nextcircle = circle;
  }
  this.draw = function(radius){
    console.log('执行:drawmediumcircle');
    if(this.min < radius && radius < this.max){
      console.log('画一个中圆 ( 10-20 )');
    }
    if(this.nextcircle){
      this.nextcircle.draw(radius)
    }
  }
}
 
var drawbigcircle = function(min,max){
  this.max = max;
  this.min = min;
  this.nextcircle;
  this.setnextdraw = function(circle){
    this.nextcircle = circle;
  }
  this.draw = function(radius){
    console.log('执行:drawbigcircle');
    if(this.min < radius && radius < this.max){
      console.log('画一个大圆 ( 20以上 )');
    }
    if(this.nextcircle){
      this.nextcircle.draw(radius)
    }
  }
}
 
function initchain(){
  var smalcircle = new drawsmalcircle(0,10);
  var mediumcircle = new drawmediumcircle(10,20);
  var bigcircle = new drawbigcircle(20,100);
 
  smalcircle.setnextdraw(mediumcircle);
  mediumcircle.setnextdraw(bigcircle);
  return smalcircle;
}
 
var circle = initchain();
circle.draw(30)
// 执行:drawsmalcircle
// 执行:drawmediumcircle
// 执行:drawbigcircle
// 画一个大圆 ( 20以上 
circle.draw(15)
// 执行:drawsmalcircle
// 执行:drawmediumcircle
// 画一个中圆 ( 10-20 )
// 执行:drawbigcircle
circle.draw(5)
// 执行:drawsmalcircle
// 画一个小圆( 10以下 )
// 执行:drawmediumcircle
// 执行:drawbigcircle

以上就是职责链模式的实例代码,drawsmalcircle,drawmediumcircle,drawbigcircle称为处理者类,处理者类保存了下一级对象的引用,

当我每执行一次draw时,程序会挨个执行职责链上的每一个方法。

职责链模式分为纯职责链和不纯职责链,纯的职责链在处理请求时,只能选择全部处理不传递或者全部传递不处理。我们这里的例子就是不纯职责链。它允许处理完成后继续向后传递。

职责链模式总结:

优点:
* 降低耦合,互相都不清楚执行顺序以及执行处理的类。
* 请求对象仅需维持一个指向其后继者的引用,简化了对象的相互连接。
* 新增修改职责链结构方便,满足开关原则。

缺点:
* 由于没有明确接受者,可能职责链走到最后都没有被正确处理。
* 职责链较长时会导致系统性能受影响。
* 建链不当,会造成循环调用,导致系统陷入死循环。

适用场景:
* 多个对象处理同一请求
* 动态创建执行顺序,流程

感兴趣的朋友可以使用在线html/css/javascript代码运行工具http://tools.jb51.net/code/htmljsrun测试上述代码运行效果。

上一篇:

下一篇: