责任链模式介绍
责任链模式(Iterator Patern),是行为型设计模式之一。什么是“链”?我们将多个节点首尾相连所构成的模型称为链,比如生活中常见的锁链,就是由一个个圆角长方形的铁环串起来的结构。对于链式结构,每个节点都可以被拆开再连接,因此,链式结构也具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,我们将这样的一种模式称为责任链模式,这样的解释是不是更通俗易懂呢?我们还是看看责任链模式的标准定义。
责任链模式的定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,只到有对象处理它为止。
责任链模式的使用场景
多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
责任链模式(Iterator Patern),是行为型设计模式之一。什么是“链”?我们将多个节点首尾相连所构成的模型称为链,比如生活中常见的锁链,就是由一个个圆角长方形的铁环串起来的结构。对于链式结构,每个节点都可以被拆开再连接,因此,链式结构也具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,我们将这样的一种模式称为责任链模式,这样的解释是不是更通俗易懂呢?我们还是看看责任链模式的标准定义。
责任链模式的定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,只到有对象处理它为止。
责任链模式的使用场景
多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
需要动态指定一组对象处理请求。
责任链模式的UML类图
责任链模式的UML类图如图9-1所示。根据类图我们可以得出如下一个责任链模式简化版的通用模式代码。
//抽象处理者
public abstract class Handler {
protected Handler successor;//下一节点的处理者
/**
* 请求处理
*
* @paran condition 请求条件
*/
public abstract void handleRequest(String condition);
}
//具体的处理者1
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
if (condition.equals("ConcreteHandler1")) {
System.out.println("ConcreteHandler1 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
//具体的处理者2
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
if (condition.equals("ConcreteHandler2")) {
System.out.println("ConcreteHandler2 handled");
return;
} else {
successor.handleRequest(condition);
}
}
}
//客户类
public class client {
public static void main(String[] args) {
//构造一个concreteHandler1对象
ConcreteHandler1 handler1 = new ConcreteHandler1();
//构造一个Concretelandler2对象
ConcreteHandler2 handler2 = new ConcreteHandler2();
//设置handler1的下一个节点
handler1.successor = handler2;
//设置handler2的下一节点
handler2.successor = handler1;
//处理请求
handler1.handleRequest("ConcreteHandler2");
}
}
角色介绍 Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用。 ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象。 上面我们说到这是一个简化版的通用模式代码,为什么这么说呢?因为对于请求来说,其形式是固定的,就是一个字符串,而判断一个节点上的对象是否能够处理该请求的标志,则是该字符串 是否与之匹配。然而在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象,类图如 图9-2所示。
首先我们来看AbstractHandler抽象处理者,其声明了处理者对象处理请求的方法和获取级别的方法,并对具体的处理转发逻辑进行了实现。
//抽象处理者public abstract class AbstractHandler { protected AbstractHandler nextHandler;//下一节点上的处理者对象 /** * 处理请求 * <p> * <p> * paran request请求对象 **/ public final void handleRequest(AbstractRequest request) { //判断当前处理者对象的处理级别是否与请求者的处理级别一致 if (getHandleLevel() == request.getRequestLevel()) { // 一致则由该处理对象处理 handle(request); } else { //否则将该请求对象转发给下一个节点上的请求对象 if (nextHandler != null) { nextHandler.handleRequest(request); } else { //当所有处理者对象均不能处理该请求时输出 System.out.println("Al1 of handler can not handle the request"); } } } /** * 获取处理者对象的处理级别 * * @return处理级别 */ protected abstract int getHandleLevel(); /* 每个处理者对象的具体处理方式 * @param request请求者对象 */ protected abstract void handle(AbstractRequest request); }
在这种情况下我们的责任转发逻辑由抽象处理类控制,而对于抽象请求者,其内部也声明了一个获取请求级别的方法,其与抽象处理者中返回的处理级别 保持对应,什么级别的处理逻辑就对应什么样的请求级别.//抽象请求者public abstract class AbstractRequest { private Object obj;//处理来器 public AbstractRequest(Object obj) { this.obj = obj; } // 获取处理的内容对象 public Object getContent() { return obj; } /** * 获取请求级别 */ public abstract int getRequestLevel(); }
其他的就不多介绍了,我们分别实现了3个请求者和3个处理者对象,逻辑很简单。//请求者public class Request1 extends AbstractRequest { public Request1(Object obj) { super(obj); } @Override public int getRequestLevel() { return 1; } } public class Request2 extends AbstractRequest { public Request2(Object obj) { super(obj); } @Override public int getRequestLevel() { return 2; } } public class Request3 extends AbstractRequest { public Request3(Object obj) { super(obj); } @Override public int getRequestLevel() { return 3; } }
//处理者public class Handler1 extends AbstractHandler { @Override protected int getHandleLevel() { return 1; } @Override protected void handle(AbstractRequest request) { System.out.println("Handle1 handle request:" + request.getRequestLevel()); }//处理者 } public class Handler2 extends AbstractHandler { @Override protected int getHandleLevel() { return 2; } @Override protected void handle(AbstractRequest request) { System.out.println("Handle2 handle request:" + request.getRequestLevel()); }//处理者 } public class Handler3 extends AbstractHandler { @Override protected int getHandleLevel() { return 3; } @Override protected void handle(AbstractRequest request) { System.out.println("Handle3 handle request:" + request.getRequestLevel()); } }
下面是客产类,具你的输出结果大家可以自行尝试,这里不再介绍。//客户类public class Client { public static void main(String[] args) { //构造3个处理者对象 AbstractHandler handler1 = new Handler1(); AbstractHandler handler2 = new Handler2(); AbstractHandler handler3 = new Handler3(); //设置当前处理者对象下一个节点的处理者对象 handler1.nextHandler = handler2; handler2.nextHandler = handler3; //构造3个请求者对象 AbstractRequest request1 = new Request1("Request1"); AbstractRequest request2 = new Request2("Request2"); AbstractRequest request3 = new Request3("Request3"); //总是从链式的首端发起请求 handler1.handleRequest(request1); handler1.handleRequest(request2); handler1.handleRequest(request3); } }