Java设计模式——职责链模式:解锁高效灵活的请求处理之道
Java 设计模式——职责链模式:解锁高效灵活的请求处理之道
职责链模式(Chain of Responsibility Pattern)是对象行为模式家族中的重要成员。它通过将多个对象连接成一条链,并沿此链传递请求,直到有对象处理它为止。这种模式解耦了请求的发送者与接收者,使得多个对象都有机会处理请求,从而增强了系统的灵活性与可维护性。
本文将深入探讨职责链模式的定义、结构、代码实现及其在实际场景中的应用。
1. 职责链模式核心概念
1.1 模式定义与特点
职责链模式的核心在于将请求的处理者串联成一条链。客户端发出请求后,请求会在链上传递,每个节点(处理者)决定是否处理该请求或将其传递给下一个节点。
主要特点:
- 解耦发送者与接收者: 客户端无需知道具体哪个对象会处理请求,只需将请求发送给链的起始节点。
- 动态灵活性: 可以动态地调整链的结构,如添加、删除或重新排列处理者,而无需修改客户端代码。
- 责任分担: 多个对象共同分担处理请求的责任,符合单一职责原则。
形象理解:
可以将职责链模式比作接力赛跑。每个选手(处理者)都有自己的能力范围。当接力棒(请求)传来时,如果当前选手有能力完成,则全力冲刺(处理请求);若力不从心,则将接力棒交给下一位选手,直到有人冲过终点线。
又如“击鼓传花”游戏:参与者围成圈(形成责任链),花(请求)依次传递。当鼓声停止(满足特定条件),持有花的人需表演节目(处理请求)。链的结构可以是直线、环形或树状,具体取决于业务逻辑需求。
1.2 模式结构
职责链模式主要包含以下两个核心角色:
抽象处理者(Handler)
- 角色: 链的基石与规则制定者。
- 职责: 定义处理请求的统一接口,通常包含一个指向下一个处理者的引用(后继者)。它规定了设置后继者的方法,并声明抽象的处理请求方法。
- 形式: 通常以抽象类或接口形式存在,为具体处理者提供行为框架。
具体处理者(ConcreteHandler)
- 角色: 请求的实际接收者与传递者。
职责: 实现抽象处理者定义的处理方法。当请求到达时,判断自身是否能处理:
- 若能处理,则执行具体逻辑。
- 若不能处理,则将请求转发给后继者(如果存在)。
2. 基础代码实现
以下是一个基于 Java 的职责链模式简单示例。该示例展示了如何构建处理者链并传递请求。
// 抽象处理者(Handler)
abstract class Handler {
// 持有下一个处理者的引用
protected Handler successor;
// 设置下一个处理者的方法
public void setSuccessor(Handler successor) {
this.successor = successor;
}
// 抽象的处理请求方法,具体处理逻辑由子类实现
public abstract void handleRequest(int request);
}
// 具体处理者 1(ConcreteHandler1)
class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(int request) {
// 如果请求在 0 到 10 之间,则由当前处理者处理
if (request >= 0 && request < 10) {
System.out.println(this.getClass().getSimpleName() + " handled request " + request);
} else if (successor != null) {
// 否则,将请求传递给下一个处理者
successor.handleRequest(request);
}
}
}
// 具体处理者 2(ConcreteHandler2)
class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 10 && request < 20) {
System.out.println(this.getClass().getSimpleName() + " handled request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者 3(ConcreteHandler3)
class ConcreteHandler3 extends Handler {
@Override
public void handleRequest(int request) {
if (request >= 20 && request < 30) {
System.out.println(this.getClass().getSimpleName() + " handled request " + request);
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 客户端测试类
public class Client {
public static void main(String[] args) {
// 创建处理者对象
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
// 设置处理者之间的链关系:h1 -> h2 -> h3
h1.setSuccessor(h2);
h2.setSuccessor(h3);
// 生成一些请求并处理
int[] requests = {2, 5, 14, 22, 18, 3, 27, 20};
for (int request : requests) {
h1.handleRequest(request);
}
}
}
3. 纯与不纯的职责链模式
根据请求是否必须被处理,职责链模式可分为两种变体:
3.1 纯职责链模式
- 定义: 要求链上的每一个处理者要么完全处理请求,要么将请求传递给下家,且请求最终必须被某个处理者处理。
- 特点: 规则严格,请求不会“落空”。
- 局限: 实现条件较为苛刻,应用场景相对有限,灵活性较低。
3.2 不纯职责链模式
- 定义: 允许请求在传递过程中,即使经过所有处理者也可能未被处理。
- 特点: 更加灵活,适应复杂多变的业务需求。
- 处理方式: 若请求未被处理,系统可采取默认策略,如记录日志、返回错误信息或执行默认操作。
- 应用: 实际开发中更为常见。例如,餐厅顾客点了菜单上没有的菜品,服务员可记录反馈或推荐其他菜品,而非强制必须满足该需求。
4. 实际应用案例:采购审批系统
职责链模式常用于审批流、异常处理等场景。以下是一个采购审批系统的示例,不同级别的管理人员拥有不同的审批权限。
// 抽象审批者(Approver)
abstract class Approver {
protected String name; // 审批者姓名
protected Approver successor; // 持有下一个审批者的引用
public Approver(String name) {
this.name = name;
}
public void setSuccessor(Approver successor) {
this.successor = successor;
}
// 抽象的审批请求方法
public abstract void processRequest(PurchaseRequest request);
}
// 主管审批者(Director)
class Director extends Approver {
public Director(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 10000.0) {
System.out.println(name + " approved request# " + request.getNumber());
} else if (successor != null) {
successor.processRequest(request);
}
}
}
// 副总裁审批者(VicePresident)
class VicePresident extends Approver {
public VicePresident(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 25000.0) {
System.out.println(name + " approved request# " + request.getNumber());
} else if (successor != null) {
successor.processRequest(request);
}
}
}
// 总裁审批者(President)
class President extends Approver {
public President(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 100000.0) {
System.out.println(name + " approved request# " + request.getNumber());
} else {
System.out.println("Request# " + request.getNumber() + " requires an executive meeting!");
}
}
}
// 采购请求类(PurchaseRequest)
class PurchaseRequest {
private double amount;
private int number;
public PurchaseRequest(double amount, int number) {
this.amount = amount;
this.number = number;
}
public double getAmount() {
return amount;
}
public int getNumber() {
return number;
}
}案例解析:
在该系统中,审批者构成了职责链:主管 -> 副总裁 -> 总裁。
- 金额 < 10,000:主管直接批准。
- 10,000 ≤ 金额 < 25,000:主管转交副总裁,副总裁批准。
- 25,000 ≤ 金额 < 100,000:逐级转交至总裁批准。
- 金额 ≥ 100,000:总裁无法直接批准,需召开高层会议(默认处理逻辑)。
若未来审批流程变更(如增加新层级或调整金额限制),只需修改相应节点或调整链结构,无需改动客户端代码,体现了模式的高可维护性。
5. 总结与展望
职责链模式通过解耦请求发送者与处理者,显著提升了系统的灵活性与扩展性。它使代码结构更加清晰,职责分明,便于应对业务规则的变化。
适用场景:
- 工作流审批系统。
- 消息处理与过滤系统。
- 异常处理机制。
- 插件化架构中的事件分发。
最佳实践:
- 可结合工厂模式创建处理者对象,简化客户端代码。
- 可结合装饰者模式动态增强处理者功能。
- 注意避免链路过长导致性能下降或调试困难。
熟练掌握并合理运用职责链模式,有助于构建更加健壮、高效的软件系统。
说明: 本文示例代码基于标准 Java 语法,适用于 Java 8 及以上版本。实际应用中请根据具体业务场景调整链式逻辑与终止条件。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。