Java设计模式之责任链模式(Chain of Responsibility模式)介绍
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.局限性就在这里。