定义
责任链模式是一种行为型设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。该模式将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
即,将请求沿着处理者链进行发送,收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。【如下图】
责任链模式的实现构成
构成
1. 抽象处理者(Handler):定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
2. 具体处理者(Concrete Handler):实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
3. 客户类(Client):创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
UML图
责任链模式的代码实现
场景描述
设计一个简单的在线购物系统,其中有一些步骤用来处理客户的订单,假设有如下几个处理步骤:
1. 验证客户信息:检查客户的基本信息是否完整和有效。
2. 库存检查:检查所订购的商品是否有库存。
3. 支付处理:处理客户的支付信息。
4. 订单确认:确认订单并发送确认信息给客户。
我们沿着上面的顺序进行链式处理,先验证客户信息,然后库存检查,然后支付处理,最后订单确认。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
每个步骤都是责任链中的一个环节,如果某一个环节出现问题,则责任链会中断并报告错误。
抽象处理者
// 处理请求的抽象类
abstract class OrderHandler {
protected OrderHandler nextHandler;
// 设置下一个处理者
public void setNextHandler(OrderHandler nextHandler) {
this.nextHandler = nextHandler;
}
// 处理订单的抽象方法
public abstract void handleOrder(Order order);
}
具体处理者
// 客户信息验证处理者
class CustomerInfoHandler extends OrderHandler {
@Override
public void handleOrder(Order order) {
if (order.getCustomerInfo() == null || order.getCustomerInfo().isEmpty()) {
System.out.println("客户信息不完整。");
return;
}
System.out.println("客户信息验证通过。");
if (nextHandler != null) {
nextHandler.handleOrder(order);
}
}
}
// 库存检查处理者
class InventoryHandler extends OrderHandler {
@Override
public void handleOrder(Order order) {
if (!order.isInStock()) {
System.out.println("商品库存不足。");
return;
}
System.out.println("商品库存充足。");
if (nextHandler != null) {
nextHandler.handleOrder(order);
}
}
}
// 支付处理者
class PaymentHandler extends OrderHandler {
@Override
public void handleOrder(Order order) {
if (!order.isPaymentProcessed()) {
System.out.println("支付处理失败。");
return;
}
System.out.println("支付处理成功。");
if (nextHandler != null) {
nextHandler.handleOrder(order);
}
}
}
// 订单确认处理者
class OrderConfirmationHandler extends OrderHandler {
@Override
public void handleOrder(Order order) {
System.out.println("订单确认并发送确认信息。");
// 最后一个处理者,不需要调用nextHandler
}
}
订单类
class Order {
/**
* 顾客信息
*/
private String customerInfo;
/**
* 是否有存货
*/
private boolean inStock;
/**
* 是否支付
*/
private boolean paymentProcessed;
public Order(String customerInfo, boolean inStock, boolean paymentProcessed) {
this.customerInfo = customerInfo;
this.inStock = inStock;
this.paymentProcessed = paymentProcessed;
}
public String getCustomerInfo() {
return customerInfo;
}
public boolean isInStock() {
return inStock;
}
public boolean isPaymentProcessed() {
return paymentProcessed;
}
}
客户端
// 客户端代码
public class ChainOfResponsibilityDemo {
public static void main(String[] args) {
// 创建责任处理链
OrderHandler customerInfoHandler = new CustomerInfoHandler();
OrderHandler inventoryHandler = new InventoryHandler();
OrderHandler paymentHandler = new PaymentHandler();
OrderHandler orderConfirmationHandler = new OrderConfirmationHandler();
// 设置责任链的顺序
customerInfoHandler.setNextHandler(inventoryHandler);
inventoryHandler.setNextHandler(paymentHandler);
paymentHandler.setNextHandler(orderConfirmationHandler);
// 创建订单
Order order = new Order("John Doe", true, true);
// 开始处理订单
customerInfoHandler.handleOrder(order);
}
}
总结
优点
1. 降低耦合度:发送者和接收者解耦,发送者无需知道具体的接收者是哪一个。
2. 责任分担:多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。每个处理者只需关注自己处理的部分,其余的交给链上的下一个处理者,符合单一职责原则。
缺点
1. 性能开销:在链比较长时,每个请求都要经过多个处理者,可能会影响性能。
2. 不确定性:请求有可能得不到处理,因为并不是所有请求都会被处理者处理。
应用场景
1. 系统处理流程需要动态调整:当系统的处理流程需要根据不同的情况进行动态调整时,可以使用责任链模式。
2. 请求的处理需要多个对象协作:例如,事件处理系统、审批流程系统等。
3. 需要在不影响其他处理者的情况下增加或移除处理者:责任链模式使得添加或移除处理者非常方便。
4. 多个对象可以处理同一个请求:例如,日志记录系统,根据日志级别将日志信息传递到不同的日志记录器进行处理。