实例讲解Java的设计模式编程中责任链模式的运用

定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
类型:行为类模式
类图:

首先来看一段代码:

public void test(int i, Request request){
  if(i==1){
    Handler1.response(request);
  }else if(i == 2){
    Handler2.response(request);
  }else if(i == 3){
    Handler3.response(request);
  }else if(i == 4){
    Handler4.response(request);
  }else{
    Handler5.response(request);
  }
}

代码的业务逻辑是这样的,方法有两个参数:整数i和一个请求request,根据i的值来决定由谁来处理request,如果i==1,由Handler1来处理,如果i==2,由Handler2来处理,以此类推。在编程中,这种处理业务的方法非常常见,所有处理请求的类有if…else…条件判断语句连成一条责任链来对请求进行处理,相信大家都经常用到。这种方法的优点是非常直观,简单明了,并且比较容易维护,但是这种方法也存在着几个比较令人头疼的问题:
代码臃肿:实际应用中的判定条件通常不是这么简单地判断是否为1或者是否为2,也许需要复杂的计算,也许需要查询数据库等等,这就会有很多额外的代码,如果判断条件再比较多,那么这个if…else…语句基本上就没法看了。
耦合度高:如果我们想继续添加处理请求的类,那么就要继续添加else if判定条件;另外,这个条件判定的顺序也是写死的,如果想改变顺序,那么也只能修改这个条件语句。
        既然缺点我们已经清楚了,就要想办法来解决。这个场景的业务逻辑很简单:如果满足条件1,则由Handler1来处理,不满足则向下传递;如果满足条件2,则由Handler2来处理,不满足则继续向下传递,以此类推,直到条件结束。其实改进的方法也很简单,就是把判定条件的部分放到处理类中,这就是责任连模式的原理。
 
责任连模式的结构
        责任连模式的类图非常简单,它由一个抽象地处理类和它的一组实现类组成:
抽象处理类:抽象处理类中主要包含一个指向下一处理类的成员变量nextHandler和一个处理请求的方法handRequest,handRequest方法的主要主要思想是,如果满足处理的条件,则有本处理类来进行处理,否则由nextHandler来处理。
具体处理类:具体处理类主要是对具体的处理逻辑和处理的适用条件进行实现。
 实例

责任链模式有两个角色:
抽象处理者(Handler)角色 :定义一个请求的接口。如果需要可以定义个一个方法用来设定和返回下家对象的引用。
具体处理者(ConcreteHandler)角色 :如果可以处理就处理请求,如果不能处理,就把请求传给下家,让下家处理。也就是说它处理自己能处理的请求且可以访问它的下家。
上述模式的测试代码如下:

package chainOfResp;
/**
 *描述:抽象处理角色
 */
public abstract class Handler {

 protected Handler successor;
 /**
  *描述:处理方法
  */
 public abstract void handlerRequest(String condition);

 public Handler getSuccessor() {
  return successor;
 }
 public void setSuccessor(Handler successor) {
  this.successor = successor;
 } 

}
package chainOfResp;
/**
 *描述:具体处理角色
 */
public class ConcreteHandler1 extends Handler {

 @Override
 public void handlerRequest(String condition) {
  // 如果是自己的责任,就自己处理,负责传给下家处理
  if(condition.equals("ConcreteHandler1")){
   System.out.println( "ConcreteHandler1 handled ");
   return ;
  }else{
   System.out.println( "ConcreteHandler1 passed ");
   getSuccessor().handlerRequest(condition);
  }
 }

}
package chainOfResp;
/**
 *描述:具体处理角色
 */
public class ConcreteHandler2 extends Handler {

 @Override
 public void handlerRequest(String condition) {
  // 如果是自己的责任,就自己处理,负责传给下家处理
  if(condition.equals("ConcreteHandler2")){
   System.out.println( "ConcreteHandler2 handled ");
   return ;
  }else{
   System.out.println( "ConcreteHandler2 passed ");
   getSuccessor().handlerRequest(condition);
  }
 }

}
package chainOfResp;
/**
 *描述:具体处理角色
 */
public class ConcreteHandlerN extends Handler {

 /**
  * 这里假设n是链的最后一个节点必须处理掉
  * 在实际情况下,可能出现环,或者是树形,
  * 这里并不一定是最后一个节点。
  *
  */
 @Override
 public void handlerRequest(String condition) {

  System.out.println( "ConcreteHandlerN handled");

 }

}
package chainOfResp;
/**
 *描述:测试类
 */
public class Client {

 /**
  *描述:
  */
 public static void main(String[] args) {

  Handler handler1 = new ConcreteHandler1();
  Handler handler2 = new ConcreteHandler2();
  Handler handlern = new ConcreteHandlerN();

  //链起来
  handler1.setSuccessor(handler2);
  handler2.setSuccessor(handlern);

  //假设这个请求是ConcreteHandler2的责任
  handler1.handlerRequest("ConcreteHandler2");

 }

}

举这样一个例子,在玩具工厂的生产车间,流水线就是一条责任链,假如一个玩具飞机有外壳装配员,引擎装配员,螺旋桨装配员,模型包装员组成。当这个物件飞机流到谁那里,谁就负责安装他负责的这一部分,这部分安装完成后流到下一个环节,知道所有环境完成。这个是一生成的责任链。还有一个质量检测链,质量检测也分多部,外壳检测,引擎检测,螺旋桨检测,包装检测。当产品留到检测员那里检测自己负责的那一块,如果有问题直接拎出来,如果没问题则传给下一个检测员,直到所有检测完成。这两个都是责任链,但是区别是,生成责任链每个人都会处理,并处理一部分;而质量检测责任链经过判断,要么处理掉,要么不处理流下去。这就是责任链的两种分类,后一种叫做纯的责任链,前一种叫做不纯的责任链,纯的责任链在实际应用中很少存在,常见的为不纯的责任链,上面的模型是模拟纯的责任链来处理的。
 

责任链模式的优缺点
        责任链模式与if…else…相比,他的耦合性要低一些,因为它把条件判定都分散到了各个处理类中,并且这些处理类的优先处理顺序可以随意设定。责任链模式也有缺点,这与if…else…语句的缺点是一样的,那就是在找到正确的处理类之前,所有的判定条件都要被执行一遍,当责任链比较长时,性能问题比较严重。
 
责任链模式的适用场景
       就像开始的例子那样,假如使用if…else…语句来组织一个责任链时感到力不从心,代码看上去很糟糕时,就可以使用责任链模式来进行重构。
 
总结
       责任链模式其实就是一个灵活版的if…else…语句,它就是将这些判定条件的语句放到了各个处理类中,这样做的优点是比较灵活了,但同样也带来了风险,比如设置处理类前后关系时,一定要特别仔细,搞对处理类前后逻辑的条件判断关系,并且注意不要在链中出现循环引用的问题。

(0)

相关推荐

  • Java设计模式之责任链模式简介

    对于使用过宏的朋友应该知道,利用宏可以实现一个键绑定多个技能.例如如果排在前面的技能有CD,则跳过此技能,执行之后的技能.记得曾经玩DK,打怪的时候,就是用一个键,一直按就行了.在servlet里的doGet和doPost方法,我们一般都把doGet请求发动到doPost里来处理,这也是一种责任链的模式. 这里,有个宏,绑定了"冰血冷脉"和"寒冰箭"两个技能,程序实例如下所示: package responsibility; /** * DOC 技能接口,要绑定的技

  • JAVA设计模式之责任链模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任. 从击鼓传花谈起 击鼓传花是一种热闹而又紧张的饮酒游戏.在酒宴上宾客依次坐定位置,由一人击鼓,击鼓

  • Java设计模式编程中的责任链模式使用示例

    责任链模式:多个对象由其对象对应下家的引用连成一条链,请求在这个链上传递,直到 链上的某一个接收对象处理此请求.因为请求的客户端并不知道链上最终是谁来处理这个请求,使得系统可以在不影响客户端的情况下动态地重新组织和分配责任, 从而避免了请求发送者与请求处理者之间的耦合. 责任链械中涉及到三种角色: 1,抽象处理者角色 2,具体处理者角色 3,请求发送者 小例子:假设去买房子,买房子就需要砍价, 卖房的人职位不同,可以优惠的价格也不同,不同职位就可以形成一个处理请求的链.我们暂定: * 基层销售员

  • 设计模式之责任链模式_动力节点Java学院整理

    定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 类型:行为类模式 类图: 首先来看一段代码: public void test(int i, Request request){ if(i==1){ Handler1.response(request); }else if(i == 2){ Handler2.response(request); }else if(i == 3){ Handler3

  • Java经典设计模式之责任链模式原理与用法详解

    本文实例讲述了Java经典设计模式之责任链模式.分享给大家供大家参考,具体如下: 责任链模式:多个对象由其对象对应下家的引用连成一条链,请求在这个链上传递,直到链上的某一个接收对象处理此请求.因为请求的客户端并不知道链上最终是谁来处理这个请求,使得系统可以在不影响客户端的情况下动态地重新组织和分配责任,从而避免了请求发送者与请求处理者之间的耦合. 责任链械中涉及到三种角色: 1,抽象处理者角色 2,具体处理者角色 3,请求发送者 小例子:假设去买房子,买房子就需要砍价, 卖房的人职位不同,可以优

  • Java设计模式之责任链模式(Chain of Responsibility模式)介绍

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request.也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去. 如何使用责任链模式 虽然这一段是如何使用CoR,但是也是演示什么是CoR. 有一个Handler接口: 复制代码

  • 实例讲解Java的设计模式编程中责任链模式的运用

    定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 类型:行为类模式 类图: 首先来看一段代码: public void test(int i, Request request){ if(i==1){ Handler1.response(request); }else if(i == 2){ Handler2.response(request); }else if(i == 3){ Handler3

  • 详解C++设计模式编程中责任链模式的应用

    职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 其思想很简单,比如考虑员工要求加薪.公司的管理者一共有三级,总经理.总监.经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权内,那么经理可以直接批准,否则将申请上交给总监.总监的处理方式也一样,总经理可以处理所有请求.这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求.给出这个例子的UML图.

  • 详解Java的设计模式编程中的原型模式

    定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 类型:创建类模式 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype.Prototype类需要具备以下两个条件: 实现Cloneable接口.在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法.在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedExcepti

  • 深入解析Java的设计模式编程中的模板方法模式

    定义:  定义一个操作中的算法的框架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 听起来好高端的样子,我的理解: 1.父类声明了若干个抽象方法(基本方法)和若干个具体方法(模板方法) 2.抽象方法是一个算法(过程)的步骤,在子类中实现 3.模板方法是一个算法(过程)的框架,在父类中已经约定好,实现对基本方法调用,完成固定的逻辑 4.一个算法(过程)的结构在父类中定义,具体的实现细节则在子类中实现 注:为了防止恶意操作,一般模板方法都加上final

  • Java设计模式中责任链模式详解

    目录 1.责任链设计模式的定义 2.责任链设计模式的优点与不足 3.责任链设计模式的实现思路 4.责任链设计模式应用实例 5.责任链设计模式应用场景 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观. 在现实生活中,一个事件需要经过多个对象处理是很常见的场景.例如,采购审批流程.请假流程等.公司员工请假,可批假的领导有部门负责人.副总经理.总经理等,但每个领导能批准的天数不同,员工必须根据需要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名.电话

  • Java 中责任链模式实现的三种方式

    责任链模式 责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止.这里就不再过多的介绍什么是责任链模式,主要来说说java中如何编写.主要从下面3个框架中的代码中介绍. servlet中的filter dubbo中的filter mybatis中的plugin 这3个框架在实现责任链方式不尽相同. servlet中的Filter servlet中分别定义了一个 Filter和Filter

  • Python设计模式行为型责任链模式

    目录 一.责任链模式 二.应用场景 三.代码示例 一.责任链模式 责任链模式,将多个处理方法连接成一条链条,请求将在这条链条上流动直到该链条中有一个节点可以处理该请求.通常这条链条是一个对象包含对另一个对象的引用而形成链条,每个节点有对请求的条件,当不满足条件将传递给下一个节点处理. 责任链模式有几个要点: 一个对象中含有另一个对象的引用以此类推形成链条. 每个对象中应该有明确的责任划分,即处理请求的条件. 链条的最后一节应该设计成通用请求处理,以免出现漏洞. 请求应该传入链条的头部 二.应用场

  • 实例解析C#设计模式编程中简单工厂模式的使用

    简单工厂模式的介绍 说到简单工厂,自然的第一个疑问当然就是什么是简单工厂模式了? 在现实生活中工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们也可以理解为负责生产对象的一个类, 我们平常编程中,当使用"new"关键字创建一个对象时,此时该类就依赖与这个对象,也就是他们之间的耦合度高,当需求变化时,我们就不得不去修改此类的源码,此时我们可以运用面向对象(OO)的很重要的原则去解决这一的问题,该原则就是--封装改变,既然要封装改变,自然也就要找到改变的代码,然后把改变的代码用类来封

  • 对比Java设计模式编程中的状态模式和策略模式

    为了能在Java应用程序中正确的使用状态模式和策略模式,开发人员需要清楚地知道这两种模式之间的区别.尽管状态模式和策略模式的结构非常相似,它们又同样遵循开闭原则,都代表着SOLID设计原则的'O',但它们的意图是完全不同的.Java中的策略模式是对一组相关的算法进行封装,给调用方提供了运行时的灵活性.调用方可以在运行时选择不同的算法,而不用修改使用策略的那个Context类.使用策略模式的经典例子包括实现加密算法,压缩算法,以及排序算法.另一方面,状态模式使用一个对象可以在不同的状态下表现出不同

  • 举例解析Java的设计模式编程中里氏替换原则的意义

    里氏替换原则,OCP作为OO的高层原则,主张使用"抽象(Abstraction)"和"多态(Polymorphism)"将设计中的静态结构改为动态结构,维持设计的封闭性."抽象"是语言提供的功能."多态"由继承语义实现. 里氏替换原则包含以下4层含义: 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法. 子类中可以增加自己特有的方法. 当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更

随机推荐