责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象依次处理同一个请求,形成一条责任链。当客户端提交一个请求时,请求沿着责任链传递,直到有一个处理者能够处理该请求为止。
概念:
在责任链模式中,通常有一个抽象处理者(Handler)类,它定义了处理请求的接口和一个后继处理者的引用。具体处理者(ConcreteHandler)继承抽象处理者,并实现请求处理的方法。每个具体处理者都决定自己能处理哪些请求,如果不能处理,则将请求传递给下一个处理者。
优点:
- 解耦: 将请求的发送者和接收者解耦,请求者不需要知道谁将处理请求,处理者也不需要知道请求的发送者是谁。
- 灵活性: 可以动态地新增或修改处理者,改变责任链结构,灵活地处理请求。
- 单一职责: 每个具体处理者只需关注自己能够处理的请求,符合单一职责原则。
缺点:
- 无保障完成: 请求可能到达链末端而得不到处理,需要事先设置好默认的处理方式或保证有一个终止处理者。
- 性能考虑: 链过长时,请求可能需要遍历整个链才能找到合适的处理者。
使用场景:
- 多级审批流程:如请假审批、报销审批等,不同级别的领导可以作为具体处理者,形成一条责任链。
- 日志记录:不同级别的日志处理器可以组成责任链,将日志信息传递给不同的处理器处理。
- 用户权限验证:多个验证器形成责任链,依次进行用户权限验证。
案例:
假设有一个电商系统,用户下单后,需要依次进行库存检查、优惠券验证、支付处理等操作。如果其中一环出现问题,后续操作将无法继续进行。
// 订单类
class Order {
private String orderNumber;
private double totalAmount;
private String couponCode;
public Order(String orderNumber, double totalAmount, String couponCode) {
this.orderNumber = orderNumber;
this.totalAmount = totalAmount;
this.couponCode = couponCode;
}
public String getOrderNumber() {
return orderNumber;
}
public double getTotalAmount() {
return totalAmount;
}
public String getCouponCode() {
return couponCode;
}
}
// 抽象处理者
abstract class OrderHandler {
protected OrderHandler successor;
public void setSuccessor(OrderHandler successor) {
this.successor = successor;
}
public abstract void handleOrder(Order order);
}
// 具体处理者 - 库存检查
class StockCheckHandler extends OrderHandler {
public void handleOrder(Order order) {
if (checkStock(order)) {
System.out.println("库存检查通过,订单号:" + order.getOrderNumber());
if (successor != null) {
successor.handleOrder(order);
}
} else {
System.out.println("库存不足,无法处理订单:" + order.getOrderNumber());
}
}
private boolean checkStock(Order order) {
// 检查库存是否足够
// 省略具体实现
return true;
}
}
// 具体处理者 - 优惠券验证
class CouponValidationHandler extends OrderHandler {
public void handleOrder(Order order) {
if (validateCoupon(order)) {
System.out.println("优惠券验证通过,订单号:" + order.getOrderNumber());
if (successor != null) {
successor.handleOrder(order);
}
} else {
System.out.println("优惠券验证失败,无法处理订单:" + order.getOrderNumber());
}
}
private boolean validateCoupon(Order order) {
// 验证优惠券是否有效
// 省略具体实现
return true;
}
}
// 具体处理者 - 支付处理
class PaymentHandler extends OrderHandler {
public void handleOrder(Order order) {
if (processPayment(order)) {
System.out.println("支付处理完成,订单号:" + order.getOrderNumber());
// 这是最后一环,不再调用 successor.handleOrder(order);
} else {
System.out.println("支付处理失败,无法处理订单:" + order.getOrderNumber());
}
}
private boolean processPayment(Order order) {
// 处理支付逻辑
// 省略具体实现
return true;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
OrderHandler stockCheckHandler = new StockCheckHandler();
OrderHandler couponValidationHandler = new CouponValidationHandler();
OrderHandler paymentHandler = new PaymentHandler();
stockCheckHandler.setSuccessor(couponValidationHandler);
couponValidationHandler.setSuccessor(paymentHandler);
Order order = new Order("12345", 100, "DISCOUNT_10_OFF");
stockCheckHandler.handleOrder(order);
}
}
在上述案例中,每个具体处理者都专注于自己的责任,并通过 setSuccessor
方法将责任传递给下一个处理者。当客户端提交一个订单时,订单会依次经过库存检查、优惠券验证和支付处理,只有在责任链上的所有处理者都处理成功时,订单才能被完整地处理。