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

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

程序员文章站 2024-03-01 21:16:04
chain of responsibility定义:chain of responsibility(cor) 是用一系列类(classes)试图处理一个请求request,...

chain of responsibility定义:chain of responsibility(cor) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request。也就是说,来了一个请求,a类先处理,如果没有处理,就传递到b类处理,如果没有处理,就传递到c类处理,就这样象一个链条(chain)一样传递下去。

如何使用责任链模式
虽然这一段是如何使用cor,但是也是演示什么是cor。

有一个handler接口:

复制代码 代码如下:

public interface handler{
  public void handlerequest();
}

这是一个处理request的事例, 如果有多种request,比如 请求帮助 请求打印 或请求格式化:
◆ 最先想到的解决方案是:在接口中增加多个请求:
复制代码 代码如下:

public interface handler{
  public void handlehelp();
  public void handleprint();
  public void handleformat();
}

具体是一段实现接口handler代码:

复制代码 代码如下:

public class concretehandler implements handler{
  private handler successor;
  public concretehandler(handler successor){
          this.successor=successor;
        }

  public void handlehelp(){
    //具体处理请求help的代码
    ...
  }

  public void handleprint(){
    //如果是print 转去处理print
    successor.handleprint();
  }
  public void handleformat(){
    //如果是format 转去处理format
    successor.handleformat();
  }

}

一共有三个这样的具体实现类,上面是处理help,还有处理print 处理format这大概是我们最常用的编程思路。

虽然思路简单明了,但是有一个扩展问题,如果我们需要再增加一个请求request种类,需要修改接口及其每一个实现。

◆ 第二方案:将每种request都变成一个接口,因此我们有以下代码 :

复制代码 代码如下:

public interface helphandler{
  public void handlehelp();
}

public interface printhandler{
  public void handleprint();
}

public interface formathandler{
  public void handleformat();
}

public class concretehandler
  implements helphandler,printhandler,formathandlet{
  private helphandler helpsuccessor;
  private printhandler printsuccessor;
  private formathandler formatsuccessor;

  public concretehandler(helphandler helpsuccessor,printhandler printsuccessor,formathandler             formatsuccessor)
  {
    this.helpsuccessor=helpsuccessor;
    this.printsuccessor=printsuccessor;
    this.formatsuccessor=formatsuccessor;
  }

  public void handlehelp(){
    .......
  }

  public void handleprint(){this.printsuccessor=printsuccessor;}

  public void handleformat(){this.formatsuccessor=formatsuccessor;}

}

这个办法在增加新的请求request情况下,只是节省了接口的修改量,接口实现concretehandler还需要修改。而且代码显然不简单美丽。


◆ 解决方案3:在handler接口中只使用一个参数化方法:

复制代码 代码如下:

public interface handler{
  public void handlerequest(string request);
}
那么handler实现代码如下:

public class concretehandler implements handler{
  private handler successor;

  public concretehandler(handler successor){
    this.successor=successor;
  }

  public void handlerequest(string request){
    if (request.equals("help")){
      //这里是处理help的具体代码
    }else
      //传递到下一个
      successor.handle(request);

    }
  }

}

这里先假设request是string类型,如果不是怎么办?当然我们可以创建一个专门类request

◆ 最后解决方案:接口handler的代码如下:

复制代码 代码如下:

public interface handler{
  public void handlerequest(request request);
}
request类的定义:

public class request{
  private string type;

  public request(string type){this.type=type;}

  public string gettype(){return type;}

  public void execute(){
    //request真正具体行为代码
  }
}


那么handler实现代码如下:
复制代码 代码如下:

public class concretehandler implements handler{
  private handler successor;

  public concretehandler(handler successor){
    this.successor=successor;
  }

  public void handlerequest(request request){
    if (request instanceof helprequest){
      //这里是处理help的具体代码
    }else if (request instanceof printrequst){
      request.execute();
    }else
      //传递到下一个
      successor.handle(request);

    }
  }

}

这个解决方案就是cor,在一个链上,都有相应职责的类,因此叫chain of responsibility。

1.cor的优点:因为无法预知来自外界的请求是属于哪种类型,每个类如果碰到它不能处理的请求只要放弃就可以。无疑这降低了类之间的耦合性。
2.cor的缺点是效率低,因为一个请求的完成可能要遍历到最后才可能完成,当然也可以用树的概念优化。 在java awt1.0中,对于鼠标按键事情的处理就是使用cor,到java.1.1以后,就使用observer代替cor。

扩展性差,因为在cor中,一定要有一个统一的接口handler.局限性就在这里。