设计模式之职责链模式

职责链模式(Chain Of  Responsibility),其含义是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止,我们可以考虑现实中的军情传递情况,以及java语言中的异常处理机制。

这个想法是给多个对象处理一个请求的机会,从而解耦发送者而后接受者。该请求沿对象链传递直至其中一个对象处理它,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不明确地知道哪一个对象将会处理它——我们说该请求有一个隐式的接收者。要沿链发转请求,并保证接收者为隐式的,每个在链上的对象都有一致的处理请求和访问链上后继者的接口。

其适用性:

有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定,

你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求,

可处理一个请求的对象集合应被动态指定。

其结构图如下:

                    设计模式之职责链模式

一个典型的对象结构可能如下所示:

      设计模式之职责链模式 

该模式有个缺陷就是一个请求可能会没有被正确配置而得不到处理,而在传递的时候丢失了。责任链模式不一定就是一个链表,只是为了方便叙述,而且顺序执行所以大都这么解释,其还可以是一个环链,或者一个树结构的一部分。

本人的实现是通过在抽象类Handle的各个子类判断是否有父类,如果有就交给父类进行Request的处理,这样虽然简单了,但也仅仅是为了实现而实现。看到过一个经典的实现是在Handle有个options属性,每个ConcreteHandle根据options的值,来决定是否把处理权交给父类,觉得这个很好,很像异常处理机制了。遂觉得自己的实现很糟,如下:

       package org.designpattern.behavioral.chainOfResponsibility;
           public abstract class Handle {
     private  Handle successor;

     protected Handle(){
     }

     public void setSuccessor(Handle successor) {
         this.successor = successor;
    }

    public Handle getSuccessor() {
        return successor;
    }

    public abstract void HandleRequest();
}

 各个具体Handle类就是实现HandleRequest方法就行了,如下所示的:

package org.designpattern.behavioral.chainOfResponsibility;
public class ConcreteHandleA extends Handle {
    public ConcreteHandleA() {
        super();
    }

    @Override
    public void HandleRequest() {
        //To change body of implemented methods use File | Settings | File Templates.
        if(this.getSuccessor() != null){
            System.out.println("deliver the control from " + this.getClass().getSimpleName() + " to the next handler.." + this.getSuccessor().getClass().getSimpleName());
            this.getSuccessor().HandleRequest();
        }else{
            System.out.println("handle this problem by ConcreteHandleA!");
        }
    }

} 

其他的ConcreteHandle类都类似实现,下面是客户端测试类:

package org.designpattern.behavioral.chainOfResponsibility;
public class Main {
    public static void main(String[] args) {
        Handle h1 = new ConcreteHandleA();
        Handle h2 = new ConcreteHandleB();
        Handle h3 = new ConcreteHandleC();

        h1.setSuccessor(h2);
        h2.setSuccessor(h3);
        h1.HandleRequest();
        h2.HandleRequest();
        h3.HandleRequest();
    }

} 

  责任链模式常与Composite模式一起使用,该模式的处理是由客户端设置的状态动态决定的,把请求传递给不同的处理对象,当然并不保证请求会一定被处理,该模式会有一定的性能损耗,如果要扩展的话,Handle由于是统一的接口需要进行修改。