设计模式之职责链模式
职责链模式(Chain Of Responsibility),其含义是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止,我们可以考虑现实中的军情传递情况,以及java语言中的异常处理机制。
这个想法是给多个对象处理一个请求的机会,从而解耦发送者而后接受者。该请求沿对象链传递直至其中一个对象处理它,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。提交请求的对象并不明确地知道哪一个对象将会处理它——我们说该请求有一个隐式的接收者。要沿链发转请求,并保证接收者为隐式的,每个在链上的对象都有一致的处理请求和访问链上后继者的接口。
其适用性:
有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定,
你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求,
可处理一个请求的对象集合应被动态指定。
其结构图如下:
一个典型的对象结构可能如下所示:
该模式有个缺陷就是一个请求可能会没有被正确配置而得不到处理,而在传递的时候丢失了。责任链模式不一定就是一个链表,只是为了方便叙述,而且顺序执行所以大都这么解释,其还可以是一个环链,或者一个树结构的一部分。
本人的实现是通过在抽象类Handle的各个子类判断是否有父类,如果有就交给父类进行Request的处理,这样虽然简单了,但也仅仅是为了实现而实现。看到过一个经典的实现是在Handle有个options属性,每个ConcreteHandle根据options的值,来决定是否把处理权交给父类,觉得这个很好,很像异常处理机制了。遂觉得自己的实现很糟,如下:
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方法就行了,如下所示的:
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类都类似实现,下面是客户端测试类:
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由于是统一的接口需要进行修改。