一、定义
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推, 通常情况下,可以通过数据链表来实现职责链模式的数据结构。
职责链模式主要包含以下角色。
- 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
- 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
- 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
责任链模式的本质是解耦请求与处理,让请求在处理链中能进行传递与被处理;理解责任链模式应当理解其模式,而不是其具体实现。责任链模式的独到之处是将其节点处理者组合成了链式结构,并允许节点自身决定是否进行请求处理或转发,相当于让请求流动起来。
二、责任链模式应用场景
在现实生活中,一个事件需要经过多个对象处理是很常见的场景。例如,采购审批流程、请假流程等。公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据需要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这无疑增加了难度。
//抽象处理者角色 public abstract class Handler { private Handler next; public void setNext(Handler next) { this.next = next; } public Handler getNext() { return next; } //处理请求的方法 public abstract void handleRequest(String request); }
//具体处理者角色1 public class ConcreteHandler1 extends Handler { public void handleRequest(String request) { if (request.equals("one")) { System.out.println("具体处理者1负责处理该请求!"); } else { if (getNext() != null) { getNext().handleRequest(request); } else { System.out.println("到了处理者1这边没有人处理该请求!"); } } } }
//具体处理者角色2 public class ConcreteHandler2 extends Handler { public void handleRequest(String request) { if (request.equals("two")) { System.out.println("具体处理者2负责处理该请求!"); } else { if (getNext() != null) { getNext().handleRequest(request); } else { System.out.println("到了处理者2这边没有人处理该请求!"); } } } }
public class ChainOfResponsibilityPattern { public static void main(String[] args) { //组装责任链 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); handler1.setNext(handler2); //提交请求 handler1.handleRequest("two"); } }
三、总结
优点:
1)你可以控制请求处理的顺序。
2)单一职责原则。 你可对发起操作和执行操作的类进行解耦。
3)开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。
缺点:
1)在组装链时,需要注意当前链节点的情况,是否要向下一节点执行,否则会导致请求未被后续责任链处理。
1)你可以控制请求处理的顺序。
2)单一职责原则。 你可对发起操作和执行操作的类进行解耦。
3)开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。
缺点:
1)在组装链时,需要注意当前链节点的情况,是否要向下一节点执行,否则会导致请求未被后续责任链处理。
补充:责任链模式一般会跟建造者模式结合应用