概念
将多个处理请求的对象连接成一条链,每个对象在链上依次处理请求,直到有对象处理完请求为止
应用场景
遇到某个请求需要经过多个处理环节,这些步骤放在一个类里处理,逻辑会非常混乱,并且修改起来也非常麻烦
使用责任链模式将这些处理分成多个对象,每个对象只处理自己负责的那一部分,并将处理结果传递到下一环节
不仅可以避免一个类内堆砌过多的业务逻辑,还能动态地调整责任链的顺序和处理方式
基本结构

1)处理者接口(Handler):声明一个处理请求的接口,通常包括一个方法handleRequest(),并且持有对下一个处理者的引用
2)具体处理者(ConcreteHandler):实现抽象处理者的处理方法,如果当前对象能够处理请求,就处理它;将请求转发给链上的下一个对象
3)客户端(Client):客负责构造责任链并发送请求,它不需要关心请求如何被处理,只需要向责任链传递请求即可
代码实现
以 “订单优惠处理” 为例
首先定义订单类
@Data
public class Order {
private double amount; // 订单金额
private boolean hasCoupon; // 是否使用了优惠券
private boolean isMember; // 是否为会员
public Order(double amount, boolean hasCoupon, boolean isMember) {
this.amount = amount;
this.hasCoupon = hasCoupon;
this.isMember = isMember;
}
}
处理者接口
处理者接口必须持有“设置下一个处理者”和“处理请求”的方法
public interface DiscountHandler {
void setNextHandler(DiscountHandler handler); // 设置下一个处理器
void applyDiscount(Order order); // 应用优惠策略
}
具体处理者
持有下一个处理者的引用,保证责任链完整,若为null则表示在责任链的末端
public class FullReductionDiscountHandler implements DiscountHandler {
private DiscountHandler nextHandler; // 下一个处理器
@Override
public void setNextHandler(DiscountHandler handler) {
this.nextHandler = handler;
}
@Override
public void applyDiscount(Order order) {
if (order.getAmount() > 200) {
System.out.println("满减折扣: -50");
order.setAmount(order.getAmount() - 50);
}
if (nextHandler != null) {
nextHandler.applyDiscount(order); // 继续传递给下一个处理器
}
}
}
public class CouponDiscountHandler implements DiscountHandler {
private DiscountHandler nextHandler;
@Override
public void setNextHandler(DiscountHandler handler) {
this.nextHandler = handler;
}
@Override
public void applyDiscount(Order order) {
if (order.hasCoupon()) {
System.out.println("优惠券折扣: -30");
order.setAmount(order.getAmount() - 30);
}
if (nextHandler != null) {
nextHandler.applyDiscount(order);
}
}
}
public class MemberDiscountHandler implements DiscountHandler {
private DiscountHandler nextHandler;
@Override
public void setNextHandler(DiscountHandler handler) {
this.nextHandler = handler;
}
@Override
public void applyDiscount(Order order) {
if (order.isMember()) {
System.out.println("会员折扣: -20");
order.setAmount(order.getAmount() - 20);
}
if (nextHandler != null) {
nextHandler.applyDiscount(order);
}
}
}
客户端调用
客户端负责构造并使用责任链
public class Client {
public static void main(String[] args) {
Order order = new Order(250, true, true); // 创建订单
// 创建各个优惠处理器
DiscountHandler fullReductionHandler = new FullReductionDiscountHandler();
DiscountHandler couponHandler = new CouponDiscountHandler();
DiscountHandler memberHandler = new MemberDiscountHandler();
// 设置责任链:优惠处理器依次连接
fullReductionHandler.setNextHandler(couponHandler);
couponHandler.setNextHandler(memberHandler);
// 开始应用优惠
fullReductionHandler.applyDiscount(order); // 从满减开始处理
System.out.println("最终订单金额: " + order.getAmount());
}
}
优缺点
优点
1)减少了耦合性:将各种处理分开,降低耦合
2)灵活处理请求:客户端能够动态构造各种责任链
3)可扩展性强:只需新增责任环节即可实现扩展
缺点
1)不易调试:责任链过长,不易判断哪一环节出现问题
