责任链模式是一种灵活的事件处理策略,它允许多个对象按照顺序处理请求,避免请求发送者与接收者之间的耦合关系。在实际工作中,通常有如下两种应用场景:操作需要经过一系列的校验,通过校验后才执行某些操作;工作流。
在编程中,我们经常需要处理各种复杂的任务,这些任务可能涉及到多个对象或者模块,这些任务之间的依赖关系并不是线性的,而是一种树形结构,这种情况下,传统的命令调用模式就无法满足我们的需求,因为它只能沿着一条路径进行,而责任链模式则提供了一种更加灵活和可扩展的解决方案。
责任链模式是一种行为设计模式,它通过将请求的发送者和接收者解耦,使一个对象可以处理多个请求,这种模式的核心思想是,每个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的硬编码。
责任链模式的基本结构如下:
1、一个Request接口,定义了一个处理请求的方法。
2、一个Handler接口,定义了一个处理请求的方法,并且可以指向下一个Handler。
3、一个具体的Handler类,实现了Handler接口。
4、一个ConcreteRequest类,实现了Request接口。
5、一个客户端代码,创建Handler对象,并将它们链接成一个链表,然后发送请求。
下面是一个简单的责任链模式的实现示例:
// Request接口 public interface Request { void handleRequest(Handler handler); } // Handler接口 public interface Handler { void setNext(Handler next); Handler getNext(); void handleRequest(Request request); } // 具体Handler类A public class ConcreteHandlerA implements Handler { private Handler next; @Override public void setNext(Handler next) { this.next = next; } @Override public Handler getNext() { return next; } @Override public void handleRequest(Request request) { if (request.getClass().equals(ConcreteRequestA.class)) { System.out.println("ConcreteHandlerA处理ConcreteRequestA"); } else if (next != null) { next.handleRequest(request); } else { System.out.println("没有处理器可以处理该请求"); } } } // 具体Handler类B public class ConcreteHandlerB implements Handler { private Handler next; @Override public void setNext(Handler next) { this.next = next; } @Override public Handler getNext() { return next; } @Override public void handleRequest(Request request) { if (request.getClass().equals(ConcreteRequestB.class)) { System.out.println("ConcreteHandlerB处理ConcreteRequestB"); } else if (next != null) { next.handleRequest(request); } else { System.out.println("没有处理器可以处理该请求"); } } } // 具体Request类A和B public class ConcreteRequestA extends Request { @Override public void handleRequest(Handler handler) { handler.handleRequest(this); } } public class ConcreteRequestB extends Request { @Override public void handleRequest(Handler handler) { handler.handleRequest(this); } }
在这个示例中,我们有两个具体的请求类型ConcreteRequestA和ConcreteRequestB,以及两个具体的处理器类型ConcreteHandlerA和ConcreteHandlerB,客户端代码创建了两个处理器对象,并将它们链接成一个链表,然后发送请求,当收到ConcreteRequestA时,ConcreteHandlerA会处理它;当收到ConcreteRequestB时,ConcreteHandlerB会处理它;如果收到其他类型的请求,那么就会沿着链表一直传递下去,直到有处理器可以处理为止。