• 作者:老汪软件技巧
  • 发表时间:2024-10-05 00:01
  • 浏览量:

定义

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

以下是责任链模式的主要特点和定义:

主要角色

Handler(抽象处理者) :

ConcreteHandler(具体处理者) :

业务

假设我们正在开发一个在线购物系统的订单处理流程。订单可能需要经过多个环节的处理,如支付验证、库存检查和物流配送安排等。

classDiagram
    class OrderHandler {
        -OrderHandler nextHandler
        +setNextHandler(OrderHandler) : void
        +handleOrder(Order) : void
    }
    class PaymentHandler {
        +handleOrder(Order) : void
    }
    class InventoryHandler {
        +handleOrder(Order) : void
    }
    class ShippingHandler {
        +handleOrder(Order) : void
    }
    class Order {
        -boolean paid
        -boolean inStock
        +Order(boolean, boolean)
        +isPaid() : boolean
        +isInStock() : boolean
    }
    PaymentHandler --> OrderHandler
    InventoryHandler --> OrderHandler
    ShippingHandler --> OrderHandler

一、定义抽象处理者和具体处理者

首先定义抽象处理者OrderHandler:

public abstract class OrderHandler {
    protected OrderHandler nextHandler;
    public void setNextHandler(OrderHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
    public abstract void handleOrder(Order order);
}

然后实现具体处理者,比如PaymentHandler(支付验证处理者)、InventoryHandler(库存检查处理者)和ShippingHandler(物流配送处理者):

public class PaymentHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (order.isPaid()) {
            System.out.println("Payment verified.");
            if (nextHandler!= null) {
                nextHandler.handleOrder(order);
            }
        } else {
            System.out.println("Payment not verified. Order cannot proceed.");
        }
    }
}
public class InventoryHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        if (order.isInStock()) {
            System.out.println("Inventory checked. Product is in stock.");
            if (nextHandler!= null) {
                nextHandler.handleOrder(order);
            }
        } else {
            System.out.println("Product out of stock. Order cannot proceed.");
        }
    }
}
public class ShippingHandler extends OrderHandler {
    @Override
    public void handleOrder(Order order) {
        System.out.println("Shipping arranged.");
    }
}

定义订单类Order:

public class Order {
    private boolean paid;
    private boolean inStock;
    public Order(boolean paid, boolean inStock) {
        this.paid = paid;
        this.inStock = inStock;
    }
    public boolean isPaid() {
        return paid;
    }
    public boolean isInStock() {
        return inStock;
    }
}

二、使用责任链模式

public class Main {
    public static void main(String[] args) {
        OrderHandler paymentHandler = new PaymentHandler();
        OrderHandler inventoryHandler = new InventoryHandler();
        OrderHandler shippingHandler = new ShippingHandler();
        paymentHandler.setNextHandler(inventoryHandler);
        inventoryHandler.setNextHandler(shippingHandler);
        Order order = new Order(true, true);
        paymentHandler.handleOrder(order);
    }
}

在这个例子中,订单依次经过支付验证、库存检查和物流配送安排等环节的处理。如果一个环节处理成功,就将请求传递给下一个环节;如果处理失败,就停止处理并给出相应的提示。这样,每个环节只需要关注自己的职责,而不需要知道整个处理流程的细节,实现了请求的发送者和接收者之间的解耦。

框架中的使用spring

在 Spring 框架中,责任链模式有一些应用场景,以下是其中一个例子:

Spring AOP(面向切面编程)中的拦截器链

Spring AOP 使用责任链模式来实现切面的拦截功能。当一个方法被切面增强时,实际上是通过一系列的拦截器(Interceptor)组成的责任链来进行处理。

每个拦截器可以在目标方法执行前后执行一些特定的逻辑,比如日志记录、性能监控、事务管理等。这些拦截器按照特定的顺序组成一个链条,当方法被调用时,请求会依次经过这些拦截器进行处理。

例如,以下是一个自定义的拦截器:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class CustomInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before method execution.");
        Object result = invocation.proceed();
        System.out.println("After method execution.");
        return result;
    }
}

在 Spring 的配置中,可以将这个拦截器添加到拦截器链中:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop">
    <aop:config>
        <aop:advisor advice-ref="customInterceptor" pointcut="execution(* com.example.service.*.*(..))"/>
    aop:config>
    <bean id="customInterceptor" class="com.example.CustomInterceptor"/>
beans>

在这个例子中,CustomInterceptor就是一个具体的处理者,多个拦截器组成的链条就类似于责任链。当目标方法被调用时,请求会依次经过这些拦截器进行处理,实现了对目标方法的增强和控制。

通过这种方式,Spring AOP 利用责任链模式灵活地实现了面向切面编程的功能,使得开发者可以在不修改目标代码的情况下,为目标方法添加各种横切关注点的逻辑。

mybatis

总结

使用场景

有多个对象可以处理一个请求,具体由哪个对象处理在运行时动态决定。

系统需要动态地指定处理一个请求的对象集合。

优点

降低了请求的发送者和接收者之间的耦合度。

增强了系统的灵活性。

缺点

不能保证请求一定会被处理。

可能会导致请求的处理延迟。