
职责链模式(Chain of Responsibility Pattern)是一种常见的行为模式。
职责链模式是一种将多个对象链接起来以处理相同请求的设计模式,就像一条流水线或接力棒传递,每个对象都有机会处理请求,如果不能处理则传递给下一个对象,直到找到能够处理的对象或传递完毕。
这种模式降低了对象间的耦合度,增强了系统的可扩展性和灵活性,使得请求的处理过程更加清晰和模块化。
简而言之,职责链模式==让请求在多个对象间“接力传递”,直到找到“合适的人”==来处理。
Chain of Responsibility Pattern: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
职责链模式:通过将多个对象连接成一条链,并沿着这条链传递请求,以避免请求的发送者与接收者之间的紧密耦合。直到链上的某个对象处理请求为止。
想象一下在图书馆借阅图书的流程。在一个大型的图书馆系统中,处理图书借阅的流程可能涉及到多个步骤和角色,每个角色都有自己特定的职责。
在这个场景中,每个角色(自助借书机、前台服务台、图书管理员、系统管理员)都是一个“处理者”,他们共同组成了一个“职责链”。当一个借阅请求出现时,它会沿着这个链传递,直到有一个“处理者”能够处理它为止。
这种流程设计降低了各个角色之间的依赖和耦合,使得借阅流程更加灵活和高效。同时,它也提高了系统的可扩展性,因为新的处理者可以很容易地添加到链中,以处理新的请求或应对新的情况。
在软件系统中,当有多个对象可以处理同一类请求时,使用职责链模式可以避免请求发送者和接收者之间的紧密耦合,使得系统更加灵活和可扩展。
职责链模式中的角色通常包括以下几种:
定义一个处理请求的接口
(可选) 实现后继链
定义一个处理请求的接口,通常包含一个方法用于处理请求和一个属性用于保存对下一个处理者的引用。
- 处理它所负责的请求
- 可访问它的后继者
- 如果可处理该请求,就处理;否则将该请求转发给它的后继者
实现抽象处理者接口,处理它所负责的请求;如果可以处理该请求就处理,否则将该请求传给它的后继者。
设置职责链
向链上的具体处理者(ConcreteHandler)对象提交请求
创建处理链,并向链的第一个处理者对象发送请求。

抽象处理者组合了自身类型的对象(定义了 successor 后继处理器属性并通过setSuccssor()方法进行赋值),体现在子类上就是每个具体的处理者可以设置后继处理器,即当前无法处理的话,递给后继处理器进行处理。
下面是一个简单的Java示例,演示了职责链模式的应用:
抽象处理者
abstract class Handler {
protected Handler successor; // 持有后继者的引用
// 设置后继者
public void setSuccessor(Handler successor) {
this.successor = successor;
}
// 处理请求的方法(声明为抽象方法,由具体处理者实现)
public abstract void handleRequest(int request);
}
具体处理者A
class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 0 && request < 10) {
System.out.println("Handler A handled request " + request);
} else if (successor != null) {
successor.handleRequest(request); // 如果不能处理,则传递给后继者
}
}
}
具体处理者B
class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println("Handler B handled request " + request);
} else if (successor != null) {
successor.handleRequest(request); // 如果不能处理,则传递给后继者
}
}
}
具体处理者C
class ConcreteHandlerC extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20) {
System.out.println("Handler C handled request " + request);
} else {
// 这里没有后继者,请求到此为止
System.out.println("No handler could process the request " + request);
}
}
}
客户类
package com.polaris.designpattern.list3.behavioral.pattern03.chainofresponsibility.classicdemo;
public class Client {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
// 设置职责链
handlerA.setSuccessor(handlerB);
handlerB.setSuccessor(handlerC);
// 发送请求
int[] requests = {2, 15, 30};
for (int request : requests) {
handlerA.handleRequest(request);
}
}
}
/* Output:
Handler A handled request 2
Handler B handled request 15
Handler C handled request 30
*///~
在上面的示例中,我们定义了三个具体处理者(A、B、C),它们分别处理不同范围的请求。在客户类中,我们创建了一个处理链,并将请求发送到链的第一个处理者(A)。如果A不能处理请求,它会将请求传递给B,依此类推。
最终,所有的请求都会被处理或者因为找不到合适的处理者而结束。
为了更直观地解释职责链模式,我们可以使用一个简单的例子:购物中心的客户服务流程。当顾客在购物中心遇到问题(如退换货、咨询商品信息等)时,他们可能会首先找到最近的店员寻求帮助。如果店员不能解决问题,他们可能会将问题转交给部门经理,如果部门经理也不能处理,问题最终可能会提交给客服中心。
生活中的例子:

抽象出抽象处理者 CustomerServiceRequestHandler 客户服务请求处理器,
店员 Clerk , 部门经理 DepartmentManager , 客服中心 CustomerServiceCenter分别对其进行实现,是请求的具体处理者,
从类图也可发现,店员Clerk 对象组合了一个请求处理器对象,即后继处理节点,在这个示例是部门经理DepartmentManager 对象,表示店员如果可以处理的客户问题,店员就进行处理,否则交给他的后继节点部门经理处理;
如果请求被流转到部门经理DepartmentManager 对象来处理,如果他能处理,则自行处理返回了,否则将客户的问题递给后继节点处理,这里是客服中心CustomerServiceCenter对象,从类图可以看出部门经理对象组合了一个客户服务请求处理器,具体是客服中心对象。
在本示例中,任何店员,部门经理处理不了的问题,客服中心都负责处理,他是最后的问题处理节点,因此它不再组合后继节点。
首先,我们定义一个处理请求的接口
public interface CustomerServiceRequestHandler {
String handleRequest(String request);
void setNextHandler(CustomerServiceRequestHandler nextHandler);
}
然后,我们创建实现该接口的类来表示不同的处理者:
1.店员 Clerk
public class Clerk implements CustomerServiceRequestHandler {
private CustomerServiceRequestHandler nextHandler;
@Override
public String handleRequest(String request) {
if (canHandleRequest(request)) {
return "Clerk handled request: " + request;
} else if (nextHandler != null) {
return nextHandler.handleRequest(request);
} else {
return "No handler could process the request: " + request;
}
}
@Override
public void setNextHandler(CustomerServiceRequestHandler nextHandler) {
this.nextHandler = nextHandler;
}
private boolean canHandleRequest(String request) {
// 假设店员只能处理商品信息查询请求
return request.startsWith("Product Info");
}
}
2.部门经理 DepartmentManager
public class DepartmentManager implements CustomerServiceRequestHandler {
private CustomerServiceRequestHandler nextHandler;
@Override
public String handleRequest(String request) {
if (canHandleRequest(request)) {
return "Department Manager handled request: " + request;
} else if (nextHandler != null) {
return nextHandler.handleRequest(request);
} else {
return "No handler could process the request: " + request;
}
}
@Override
public void setNextHandler(CustomerServiceRequestHandler nextHandler) {
this.nextHandler = nextHandler;
}
private boolean canHandleRequest(String request) {
// 假设部门经理可以处理退货请求
return request.startsWith("Return an item");
}
}
3.客服中心 CustomerServiceCenter
public class CustomerServiceCenter implements CustomerServiceRequestHandler {
@Override
public String handleRequest(String request) {
return "Customer Service Center handled request: " + request;
}
@Override
public void setNextHandler(CustomerServiceRequestHandler nextHandler) {
// 客服中心是链的末尾,不需要设置下一个处理者
// 这里可以抛出一个异常或者忽略这个调用
}
}
最后,我们可以创建一个客户端类来演示如何使用这个职责链
public class CustomerServiceChainDemo {
public static void main(String[] args) {
// 创建处理者实例
CustomerServiceRequestHandler clerk = new Clerk();
CustomerServiceRequestHandler manager = new DepartmentManager();
CustomerServiceRequestHandler center = new CustomerServiceCenter();
// 构建职责链
clerk.setNextHandler(manager);
manager.setNextHandler(center);
// 模拟顾客提交请求
//查询商品信息
String request1 = "Product Info 123";
String result1 = clerk.handleRequest(request1);
System.out.println(result1); // 输出:Clerk handled request: Product Info 123
//退货
String request2 = "Return an item";
String result2 = clerk.handleRequest(request2);
System.out.println(result2); // 输出:Department Manager handled request: Return an item
//服务投诉
String request3 = "Complaint about service";
String result3 = clerk.handleRequest(request3);
System.out.println(result3); // 输出:Customer Service Center handled request: Complaint about service
}
}
/* Output:
Clerk handled request: Product Info 123
Department Manager handled request: Return an item
Customer Service Center handled request: Complaint about service
*///~
在这个例子中,我们模拟了三种不同类型的顾客请求,并展示了它们如何通过职责链被不同的处理者处理。如果一个处理者不能处理请求,它会将请求传递给链中的下一个处理者,直到找到能够处理该请求的处理者,或者到达链的末尾。
