设计模式行为型
责任链模式
使多个对象都有机会处理请求,从而避免请求的发送者和接受者间的耦合,将这些对象连成一条链,并向这条链传递请求,直到有个对象处理它为止。
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
角色:
●
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
●
具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
类图:
代码实现:
第一种实现方式如下所示,其中HandlerChain 是处理器链,从数据结构的角度来看,它就是一个记录了链头、链尾的链表。其中,记录链尾是为了方便添加处理器。
public abstract class Handler {
protected Handler successor = null;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public final void handle() {
boolean handled = doHandle();
if (successor != null && !handled) {
successor.handle();
}
}
protected abstract boolean doHandle();
}
public class HandlerA extends Handler {
@Override
public boolean doHandle() {
boolean handled = true;
System.out.println("handle a");
return handled;
}
}
public class HandlerB extends Handler {
@Override
public boolean doHandle() {
boolean handled = false;
System.out.println("handle b");
return handled;
}
}
public class HandlerChain {
private Handler head;
private Handler tail;
public void addHandler(Handler handler) {
if(head==null) {
head = handler;
tail = handler;
return;
}
tail.setSuccessor(handler);
tail=handler;
}
public void handle() {
if (head != null) {
head.handle();
}
}
}
public class Context {
public static void main(String[] args) {
HandlerA handlerA = new HandlerA();
HandlerB handlerB = new HandlerB();
HandlerChain handlerChain = new HandlerChain();
handlerChain.addHandler(handlerA);
handlerChain.addHandler(handlerB);
handlerChain.handle();
}
}
第二种实现方式,代码如下所示。这种实现方式更加简单。HandlerChain 类用数组而非链表来保存所有的处理器,并且需要在 HandlerChain 的 handle() 函数中,依次调用每个处理器的 handle() 函数。
public abstract class Handler {
public abstract boolean handle();
}
public class HandlerA extends Handler {
@Override
public boolean handle() {
boolean handled = true;
System.out.println("handle a");
return handled;
}
}
public class HandlerB extends Handler {
@Override
public boolean handle() {
boolean handled = false;
System.out.println("handle b");
return handled;
}
}
public class HandlerChain {
private List<Handler> handlers = new ArrayList<Handler>();
public void addHandler(Handler handler) {
this.handlers.add(handler);
}
public void handle() {
for (Handler handler : handlers) {
boolean handled = handler.handle();
if (!handled) {
break;
}
}
}
}
public class Context {
public static void main(String[] args) {
HandlerA handlerA = new HandlerA();
HandlerB handlerB = new HandlerB();
HandlerChain handlerChain = new HandlerChain();
handlerChain.addHandler(handlerA);
handlerChain.addHandler(handlerB);
handlerChain.handle();
}
}