责任链模式是一种行为型设计模式,它允许将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求为止。每个处理者都持有对下一个处理者的引用,从而形成一条链。
核心思想
- 解耦:请求的发送者不需要知道哪个对象会处理请求,处理者之间也互不依赖。
- 动态组合:可以在运行时灵活地调整链的顺序或成员。
- 职责分离:每个处理者只关注自己能够处理的请求类型,不能处理的就转发给下一个。
主要角色
- 抽象处理器(Handler) :定义处理请求的接口,并持有下一个处理者的引用。
- 具体处理器(ConcreteHandler) :实现具体的处理逻辑,决定自己处理还是转发。
- 客户端(Client) :创建链,并将请求提交给链的第一个处理者。
代码案例:订单折扣处理链
假设一个电商系统根据订单金额给予不同的折扣:
- 订单金额 ≥ 1000 元 → 享受 9 折优惠
- 订单金额 ≥ 500 元 → 享受 95 折优惠
- 其他情况 → 无折扣
我们可以用责任链模式来依次尝试这些折扣规则,一旦某个规则匹配,就应用折扣并停止传递。
Java 实现
java
// 1. 抽象处理器:折扣处理器
abstract class DiscountHandler {
protected DiscountHandler next;
public void setNext(DiscountHandler next) {
this.next = next;
}
// 处理订单折扣,返回最终价格
public abstract double handleDiscount(double amount);
}
// 2. 具体处理器:高额折扣(满1000打9折)
class HighAmountDiscountHandler extends DiscountHandler {
@Override
public double handleDiscount(double amount) {
if (amount >= 1000) {
double discounted = amount * 0.9;
System.out.println("满1000元,享受9折优惠,折后价:" + discounted);
return discounted;
} else if (next != null) {
return next.handleDiscount(amount);
}
return amount; // 无后续处理器,原价
}
}
// 3. 具体处理器:中等折扣(满500打95折)
class MediumAmountDiscountHandler extends DiscountHandler {
@Override
public double handleDiscount(double amount) {
if (amount >= 500) {
double discounted = amount * 0.95;
System.out.println("满500元,享受95折优惠,折后价:" + discounted);
return discounted;
} else if (next != null) {
return next.handleDiscount(amount);
}
return amount;
}
}
// 4. 具体处理器:无折扣(兜底)
class NoDiscountHandler extends DiscountHandler {
@Override
public double handleDiscount(double amount) {
System.out.println("无优惠,原价:" + amount);
return amount;
}
}
// 5. 客户端
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
// 创建处理器
HighAmountDiscountHandler highHandler = new HighAmountDiscountHandler();
MediumAmountDiscountHandler mediumHandler = new MediumAmountDiscountHandler();
NoDiscountHandler noHandler = new NoDiscountHandler();
// 构建链:高额 -> 中等 -> 无折扣
highHandler.setNext(mediumHandler);
mediumHandler.setNext(noHandler);
// 测试不同订单金额
System.out.println("===== 订单金额:1200 =====");
double price1 = highHandler.handleDiscount(1200);
System.out.println("最终支付:" + price1 + "\n");
System.out.println("===== 订单金额:600 =====");
double price2 = highHandler.handleDiscount(600);
System.out.println("最终支付:" + price2 + "\n");
System.out.println("===== 订单金额:300 =====");
double price3 = highHandler.handleDiscount(300);
System.out.println("最终支付:" + price3);
}
}
运行结果
text
===== 订单金额:1200 =====
满1000元,享受9折优惠,折后价:1080.0
最终支付:1080.0
===== 订单金额:600 =====
满500元,享受95折优惠,折后价:570.0
最终支付:570.0
===== 订单金额:300 =====
无优惠,原价:300.0
最终支付:300.0
模式要点
- 请求沿链传递:每个处理器决定是否处理,如果不处理就调用
next继续传递。 - 同步执行:所有处理都在当前线程内顺序完成,没有持久化或异步等待。
- 灵活扩展:新增折扣规则只需添加新的处理器,并调整链的组装顺序即可,无需修改已有代码。
责任链模式 vs 审批流
正如你之前提到的,经典的 GoF 责任链模式是同步的,所有处理者都在同一个方法调用栈中立即执行。而审批流往往需要持久化、人工参与、异步推进,因此直接套用责任链模式并不合适。但在一些纯规则的、自动化的校验链(如权限校验、数据校验)中,责任链模式依然是非常优雅的选择。