1. 概述
责任链模式是一种行为设计模式,允许你将请求沿着处理者链并进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者
2. 问题
假如你正在开发一个在线订购系统。 你希望对系统访问进行限制, 只允许认证用户创建订单。 此外, 拥有管理权限的用户也拥有所有订单的完全访问权限。
接下来,你不断优化检查步骤和性能:
检查代码本来就已经混乱不堪, 而每次新增功能都会使其更加臃肿。 修改某个检查步骤有时会影响其他的检查步骤。
3. 解决方案
责任链模式把一系列的检查步骤抽象成独立的处理者对象。每个处理者对象都执行一个检查操作,接收请求及其数据作为参数传递给方法中进行处理。
责任链模式将一系列处理者连接成链条,每个处理者都保存着对下一个处理者的引用。处理者除了执行请求处理外,还负责将请求沿着链条传递。请求会在整个链条上传递,直到被处理为止。
最重要的是: 处理者可以决定不再沿着链传递请求, 这可高效地取消所有后续处理步骤。
在我们的订购系统示例中, 处理者会在进行请求处理工作后决定是否继续沿着链传递请求。 如果请求中包含正确的数据, 所有处理者都将执行自己的主要行为, 无论该行为是身份验证还是数据缓存。
4. 责任链模式结构
5. 使用场景
- 当必须按顺序执行多个处理者时,可以使用该模式
- 当程序需要使用不同方式处理不同种类请求,而且请求类型和顺序预先未知时,可以使用责任链模式。
- 该模式能将多个处理者连接成一条链。 接收到请求后, 它会 “询问” 每个处理者是否能够对其进行处理。 这样所有处理者都有机会来处理请求。
- 如果所需处理者及其顺序必须在运行时进行改变,可以使用责任链模式
- 如果在处理者类中有对引用成员变量的设定方法, 你将能动态地插入和移除处理者, 或者改变其顺序
6. 实现方式以及代码实例
实现方式:
实现责任链模式的一般步骤如下:
- 定义请求类:创建一个表示请求的类,其中包含需要处理的相关数据。
- 定义处理者接口:创建一个处理者接口,声明处理请求的方法。这个接口可以包含一个设置下一个处理者的方法,以便构成责任链。
- 实现具体处理者:针对处理者接口,创建具体的处理者类,并实现处理请求的方法。每个具体处理者类负责处理特定类型的请求,如果自己无法处理,则将请求传递给下一个处理者。
- 构建责任链:在客户端代码中创建具体处理者对象,并使用设置下一个处理者的方法将它们连接成责任链。
- 发起请求:创建请求对象,并将请求传递给责任链的第一个处理者。
通过这些步骤,就可以实现责任链模式,使得请求在责任链中传递,并由合适的处理者进行处理。
示例:
假设你是一个公司的员工,你想要申请假期。公司规定,假期申请需要经过三个部门的批准:人事部、部门经理和总经理。这里就可以使用责任链模式来处理假期申请。
// 定义请求类
class LeaveRequest {
private int days;
public LeaveRequest(int days) {
this.days = days;
}
public int getDays() {
return days;
}
}
// 定义处理者接口
interface LeaveHandler {
void handleRequest(LeaveRequest request);
}
// 具体处理者:人事部
class HRDepartment implements LeaveHandler {
private LeaveHandler nextHandler;
@Override
public void handleRequest(LeaveRequest request) {
if (request.getDays() <= 3) {
System.out.println("人事部批准了假期申请");
} else {
nextHandler.handleRequest(request);
}
}
public void setNextHandler(LeaveHandler nextHandler) {
this.nextHandler = nextHandler;
}
}
// 具体处理者:部门经理
class DepartmentManager implements LeaveHandler {
private LeaveHandler nextHandler;
@Override
public void handleRequest(LeaveRequest request) {
if (request.getDays() <= 7) {
System.out.println("部门经理批准了假期申请");
} else {
nextHandler.handleRequest(request);
}
}
public void setNextHandler(LeaveHandler nextHandler) {
this.nextHandler = nextHandler;
}
}
// 具体处理者:总经理
class GeneralManager implements LeaveHandler {
@Override
public void handleRequest(LeaveRequest request) {
System.out.println("总经理批准了假期申请");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
LeaveRequest request = new LeaveRequest(5);
HRDepartment hr = new HRDepartment();
DepartmentManager manager = new DepartmentManager();
GeneralManager generalManager = new GeneralManager();
hr.setNextHandler(manager);
manager.setNextHandler(generalManager);
hr.handleRequest(request);
}
}