设计模式-责任链模式详解

责任链模式详解

目录

  1. 责任链模式简介
  2. 核心流程
  3. 重难点分析
  4. Spring中的源码分析
  5. 具体使用场景
  6. 面试高频点
  7. 使用总结

责任链模式简介

定义

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

核心思想

  • 解耦发送者和接收者:请求发送者不需要知道具体哪个对象处理请求
  • 动态链式处理:可以在运行时动态构建处理链
  • 灵活配置:可以灵活添加、删除、修改处理节点
  • 单一职责:每个处理者只负责处理自己能处理的请求

模式结构

  • Handler(抽象处理者):定义处理请求的接口,实现后继链
  • ConcreteHandler(具体处理者):处理它所负责的请求,可访问它的后继者
  • Client(客户端):向链上的具体处理者对象提交请求

核心流程

责任链模式流程图

请求处理 处理链 是 否 是 否 是 否 请求验证 业务处理 结果返回 处理者1 处理者2 处理者3 处理者N 客户端发送请求 第一个处理者 能否处理? 处理请求 传递给下一个处理者 是否有下一个处理者? 下一个处理者 无法处理请求 能否处理? 返回处理结果 返回无法处理

基本实现流程

1. 定义抽象处理者
java 复制代码
// 抽象处理者
public abstract class Handler {
    protected Handler nextHandler;
  
    public void setNext(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
  
    public Handler getNext() {
        return nextHandler;
    }
  
    // 处理请求的抽象方法
    public abstract void handleRequest(Request request);
  
    // 模板方法:定义处理流程
    public final void process(Request request) {
        if (canHandle(request)) {
            handleRequest(request);
        } else if (nextHandler != null) {
            nextHandler.process(request);
        } else {
            System.out.println("无法处理请求: " + request);
        }
    }
  
    // 判断是否能处理请求
    protected abstract boolean canHandle(Request request);
}
2. 定义请求类
java 复制代码
// 请求类
public class Request {
    private String type;
    private String content;
    private int level;
  
    public Request(String type, String content, int level) {
        this.type = type;
        this.content = content;
        this.level = level;
    }
  
    // getter和setter方法
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
  
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
  
    public int getLevel() { return level; }
    public void setLevel(int level) { this.level = level; }
  
    @Override
    public String toString() {
        return "Request{" +
                "type='" + type + '\'' +
                ", content='" + content + '\'' +
                ", level=" + level +
                '}';
    }
}
3. 实现具体处理者
java 复制代码
// 具体处理者 - 初级处理者
public class JuniorHandler extends Handler {
    @Override
    protected boolean canHandle(Request request) {
        return request.getLevel() <= 1;
    }
  
    @Override
    public void handleRequest(Request request) {
        System.out.println("初级处理者处理请求: " + request);
    }
}

// 具体处理者 - 中级处理者
public class MiddleHandler extends Handler {
    @Override
    protected boolean canHandle(Request request) {
        return request.getLevel() <= 3;
    }
  
    @Override
    public void handleRequest(Request request) {
        System.out.println("中级处理者处理请求: " + request);
    }
}

// 具体处理者 - 高级处理者
public class SeniorHandler extends Handler {
    @Override
    protected boolean canHandle(Request request) {
        return request.getLevel() <= 5;
    }
  
    @Override
    public void handleRequest(Request request) {
        System.out.println("高级处理者处理请求: " + request);
    }
}
4. 客户端使用
java 复制代码
public class Client {
    public static void main(String[] args) {
        // 创建处理者
        Handler junior = new JuniorHandler();
        Handler middle = new MiddleHandler();
        Handler senior = new SeniorHandler();
      
        // 构建责任链
        junior.setNext(middle);
        middle.setNext(senior);
      
        // 创建请求
        Request request1 = new Request("简单请求", "处理简单问题", 1);
        Request request2 = new Request("复杂请求", "处理复杂问题", 4);
        Request request3 = new Request("困难请求", "处理困难问题", 6);
      
        // 处理请求
        junior.process(request1);
        junior.process(request2);
        junior.process(request3);
    }
}

重难点分析

重难点1:责任链的构建和管理

问题描述

如何动态构建和管理责任链,支持链的添加、删除、修改。

解决方案
java 复制代码
// 责任链管理器
public class ChainManager {
    private Handler firstHandler;
    private Handler lastHandler;
    private List<Handler> handlers = new ArrayList<>();
  
    public ChainManager addHandler(Handler handler) {
        if (firstHandler == null) {
            firstHandler = handler;
            lastHandler = handler;
        } else {
            lastHandler.setNext(handler);
            lastHandler = handler;
        }
        handlers.add(handler);
        return this;
    }
  
    public ChainManager removeHandler(Handler handler) {
        if (handlers.remove(handler)) {
            rebuildChain();
        }
        return this;
    }
  
    public ChainManager insertHandler(Handler handler, int index) {
        if (index < 0 || index > handlers.size()) {
            throw new IllegalArgumentException("索引超出范围");
        }
        handlers.add(index, handler);
        rebuildChain();
        return this;
    }
  
    private void rebuildChain() {
        firstHandler = null;
        lastHandler = null;
        for (Handler handler : handlers) {
            if (firstHandler == null) {
                firstHandler = handler;
                lastHandler = handler;
            } else {
                lastHandler.setNext(handler);
                lastHandler = handler;
            }
        }
    }
  
    public void process(Request request) {
        if (firstHandler != null) {
            firstHandler.process(request);
        } else {
            System.out.println("责任链为空,无法处理请求");
        }
    }
  
    public List<Handler> getHandlers() {
        return new ArrayList<>(handlers);
    }
}

// 使用示例
public class ChainManagerDemo {
    public static void main(String[] args) {
        ChainManager manager = new ChainManager();
      
        // 添加处理者
        manager.addHandler(new JuniorHandler())
               .addHandler(new MiddleHandler())
               .addHandler(new SeniorHandler());
      
        // 处理请求
        Request request = new Request("测试请求", "测试内容", 2);
        manager.process(request);
      
        // 动态添加处理者
        manager.addHandler(new EmergencyHandler());
      
        // 处理紧急请求
        Request emergencyRequest = new Request("紧急请求", "紧急内容", 10);
        manager.process(emergencyRequest);
    }
}

重难点2:责任链的终止条件

问题描述

如何设置责任链的终止条件,避免无限循环。

解决方案
java 复制代码
// 带终止条件的责任链
public abstract class TerminableHandler extends Handler {
    protected boolean terminated = false;
  
    public void setTerminated(boolean terminated) {
        this.terminated = terminated;
    }
  
    public boolean isTerminated() {
        return terminated;
    }
  
    @Override
    public final void process(Request request) {
        if (terminated) {
            System.out.println("责任链已终止,无法处理请求");
            return;
        }
      
        if (canHandle(request)) {
            handleRequest(request);
            // 处理完成后可以选择终止链
            if (shouldTerminate(request)) {
                terminated = true;
            }
        } else if (nextHandler != null) {
            nextHandler.process(request);
        } else {
            System.out.println("无法处理请求: " + request);
        }
    }
  
    // 子类可以重写此方法决定是否终止链
    protected boolean shouldTerminate(Request request) {
        return false;
    }
}

// 具体处理者实现
public class TerminableJuniorHandler extends TerminableHandler {
    @Override
    protected boolean canHandle(Request request) {
        return request.getLevel() <= 1;
    }
  
    @Override
    public void handleRequest(Request request) {
        System.out.println("初级处理者处理请求: " + request);
    }
  
    @Override
    protected boolean shouldTerminate(Request request) {
        // 处理紧急请求后终止链
        return "紧急".equals(request.getType());
    }
}

重难点3:责任链的性能优化

问题描述

如何优化责任链的性能,避免不必要的处理。

解决方案
java 复制代码
// 带缓存的责任链
public class CachedHandler extends Handler {
    private final Map<String, Handler> handlerCache = new ConcurrentHashMap<>();
    private final Map<String, Boolean> canHandleCache = new ConcurrentHashMap<>();
  
    @Override
    public void process(Request request) {
        String requestKey = generateRequestKey(request);
      
        // 检查缓存
        Boolean canHandle = canHandleCache.get(requestKey);
        if (canHandle == null) {
            canHandle = canHandle(request);
            canHandleCache.put(requestKey, canHandle);
        }
      
        if (canHandle) {
            handleRequest(request);
        } else if (nextHandler != null) {
            nextHandler.process(request);
        } else {
            System.out.println("无法处理请求: " + request);
        }
    }
  
    private String generateRequestKey(Request request) {
        return request.getType() + "_" + request.getLevel();
    }
  
    public void clearCache() {
        handlerCache.clear();
        canHandleCache.clear();
    }
}

// 并行处理的责任链
public class ParallelHandler extends Handler {
    private final ExecutorService executor = Executors.newFixedThreadPool(10);
  
    @Override
    public void process(Request request) {
        if (canHandle(request)) {
            // 并行处理
            CompletableFuture.runAsync(() -> handleRequest(request), executor);
        } else if (nextHandler != null) {
            nextHandler.process(request);
        } else {
            System.out.println("无法处理请求: " + request);
        }
    }
  
    public void shutdown() {
        executor.shutdown();
    }
}

重难点4:责任链的异常处理

问题描述

如何在责任链中处理异常,确保链的稳定性。

解决方案
java 复制代码
// 带异常处理的责任链
public abstract class ExceptionHandler extends Handler {
    @Override
    public final void process(Request request) {
        try {
            if (canHandle(request)) {
                handleRequest(request);
            } else if (nextHandler != null) {
                nextHandler.process(request);
            } else {
                System.out.println("无法处理请求: " + request);
            }
        } catch (Exception e) {
            handleException(request, e);
        }
    }
  
    protected void handleException(Request request, Exception e) {
        System.out.println("处理请求时发生异常: " + e.getMessage());
        // 可以选择继续传递给下一个处理者
        if (nextHandler != null) {
            nextHandler.process(request);
        }
    }
}

// 具体处理者实现
public class ExceptionHandlingHandler extends ExceptionHandler {
    @Override
    protected boolean canHandle(Request request) {
        return request.getLevel() <= 2;
    }
  
    @Override
    public void handleRequest(Request request) {
        // 模拟可能抛出异常的处理
        if (request.getContent().contains("异常")) {
            throw new RuntimeException("处理异常");
        }
        System.out.println("处理请求: " + request);
    }
}

Spring中的源码分析

Spring MVC的HandlerInterceptor

java 复制代码
// HandlerInterceptor接口
public interface HandlerInterceptor {
    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
  
    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }
  
    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}

// HandlerInterceptorAdapter
public abstract class HandlerInterceptorAdapter implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
  
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
  
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

// HandlerExecutionChain
public class HandlerExecutionChain {
    private final Object handler;
    private HandlerInterceptor[] interceptors;
    private List<HandlerInterceptor> interceptorList;
    private int interceptorIndex = -1;
  
    public HandlerExecutionChain(Object handler) {
        this(handler, (HandlerInterceptor[]) null);
    }
  
    public HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... interceptors) {
        this.handler = handler;
        this.interceptors = interceptors;
    }
  
    public void addInterceptor(HandlerInterceptor interceptor) {
        initInterceptorList();
        this.interceptorList.add(interceptor);
        updateInterceptorsArray();
    }
  
    public void addInterceptor(int index, HandlerInterceptor interceptor) {
        initInterceptorList();
        this.interceptorList.add(index, interceptor);
        updateInterceptorsArray();
    }
  
    public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = 0; i < interceptors.length; i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);
                    return false;
                }
                this.interceptorIndex = i;
            }
        }
        return true;
    }
  
    public void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = interceptors.length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                interceptor.postHandle(request, response, this.handler, mv);
            }
        }
    }
  
    public void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = this.interceptorIndex; i >= 0; i--) {
                HandlerInterceptor interceptor = interceptors[i];
                try {
                    interceptor.afterCompletion(request, response, this.handler, ex);
                } catch (Throwable ex2) {
                    logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
                }
            }
        }
    }
}

Spring Security的FilterChain

java 复制代码
// FilterChainProxy
public class FilterChainProxy extends GenericFilterBean {
    private List<SecurityFilterChain> filterChains;
    private FilterChainValidator filterChainValidator = new NullFilterChainValidator();
    private HttpFirewall firewall = new StrictHttpFirewall();
  
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
        if (clearContext) {
            try {
                request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
                doFilterInternal(request, response, chain);
            } finally {
                SecurityContextHolder.clearContext();
                request.removeAttribute(FILTER_APPLIED);
            }
        } else {
            doFilterInternal(request, response, chain);
        }
    }
  
    private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        FirewalledRequest firewallRequest = this.firewall.getFirewalledRequest((HttpServletRequest) request);
        HttpServletResponse firewallResponse = this.firewall.getFirewalledResponse((HttpServletResponse) response);
      
        List<Filter> filters = getFilters(firewallRequest);
      
        if (filters == null || filters.size() == 0) {
            firewallRequest.reset();
            chain.doFilter(firewallRequest, firewallResponse);
            return;
        }
      
        VirtualFilterChain virtualFilterChain = new VirtualFilterChain(firewallRequest, chain, filters);
        virtualFilterChain.doFilter(firewallRequest, firewallResponse);
    }
  
    private List<Filter> getFilters(HttpServletRequest request) {
        for (SecurityFilterChain chain : filterChains) {
            if (chain.matches(request)) {
                return chain.getFilters();
            }
        }
        return null;
    }
}

// VirtualFilterChain
private static class VirtualFilterChain implements FilterChain {
    private final FilterChain originalChain;
    private final List<Filter> additionalFilters;
    private final FirewalledRequest firewalledRequest;
    private final int size;
    private int currentPosition = 0;
  
    private VirtualFilterChain(FirewalledRequest firewalledRequest, FilterChain originalChain, List<Filter> additionalFilters) {
        this.firewalledRequest = firewalledRequest;
        this.originalChain = originalChain;
        this.additionalFilters = additionalFilters;
        this.size = additionalFilters.size();
    }
  
    @Override
    public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        if (currentPosition == size) {
            if (logger.isDebugEnabled()) {
                logger.debug(UrlUtils.buildRequestUrl(firewalledRequest) + " reached end of additional filter chain; proceeding with original chain");
            }
            originalChain.doFilter(request, response);
        } else {
            currentPosition++;
            Filter nextFilter = additionalFilters.get(currentPosition - 1);
            if (logger.isDebugEnabled()) {
                logger.debug(UrlUtils.buildRequestUrl(firewalledRequest) + " at position " + currentPosition + " of " + size + " in additional filter chain; firing Filter: '" + nextFilter.getClass().getSimpleName() + "'");
            }
            nextFilter.doFilter(request, response, this);
        }
    }
}

具体使用场景

1. 权限验证链

java 复制代码
// 权限验证处理器
public abstract class PermissionHandler {
    protected PermissionHandler nextHandler;
  
    public void setNext(PermissionHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
  
    public boolean checkPermission(User user, String resource) {
        if (canHandle(user, resource)) {
            return handlePermission(user, resource);
        } else if (nextHandler != null) {
            return nextHandler.checkPermission(user, resource);
        } else {
            return false;
        }
    }
  
    protected abstract boolean canHandle(User user, String resource);
    protected abstract boolean handlePermission(User user, String resource);
}

// 角色权限验证
public class RolePermissionHandler extends PermissionHandler {
    @Override
    protected boolean canHandle(User user, String resource) {
        return user.getRole() != null;
    }
  
    @Override
    protected boolean handlePermission(User user, String resource) {
        return user.getRole().hasPermission(resource);
    }
}

// 资源权限验证
public class ResourcePermissionHandler extends PermissionHandler {
    @Override
    protected boolean canHandle(User user, String resource) {
        return resource.startsWith("/admin/");
    }
  
    @Override
    protected boolean handlePermission(User user, String resource) {
        return user.isAdmin();
    }
}

// 时间权限验证
public class TimePermissionHandler extends PermissionHandler {
    @Override
    protected boolean canHandle(User user, String resource) {
        return resource.startsWith("/time/");
    }
  
    @Override
    protected boolean handlePermission(User user, String resource) {
        LocalTime now = LocalTime.now();
        return now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(18, 0));
    }
}

// 使用示例
public class PermissionChainDemo {
    public static void main(String[] args) {
        // 创建权限验证链
        PermissionHandler roleHandler = new RolePermissionHandler();
        PermissionHandler resourceHandler = new ResourcePermissionHandler();
        PermissionHandler timeHandler = new TimePermissionHandler();
      
        roleHandler.setNext(resourceHandler);
        resourceHandler.setNext(timeHandler);
      
        // 创建用户
        User user = new User("admin", "ADMIN");
      
        // 验证权限
        boolean hasPermission1 = roleHandler.checkPermission(user, "/user/profile");
        boolean hasPermission2 = roleHandler.checkPermission(user, "/admin/users");
        boolean hasPermission3 = roleHandler.checkPermission(user, "/time/report");
      
        System.out.println("用户权限验证结果:");
        System.out.println("/user/profile: " + hasPermission1);
        System.out.println("/admin/users: " + hasPermission2);
        System.out.println("/time/report: " + hasPermission3);
    }
}

2. 日志处理链

java 复制代码
// 日志处理器
public abstract class LogHandler {
    protected LogHandler nextHandler;
  
    public void setNext(LogHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
  
    public void handleLog(LogEntry logEntry) {
        if (canHandle(logEntry)) {
            processLog(logEntry);
        }
      
        if (nextHandler != null) {
            nextHandler.handleLog(logEntry);
        }
    }
  
    protected abstract boolean canHandle(LogEntry logEntry);
    protected abstract void processLog(LogEntry logEntry);
}

// 控制台日志处理器
public class ConsoleLogHandler extends LogHandler {
    @Override
    protected boolean canHandle(LogEntry logEntry) {
        return logEntry.getLevel().ordinal() >= LogLevel.INFO.ordinal();
    }
  
    @Override
    protected void processLog(LogEntry logEntry) {
        System.out.println("控制台日志: " + logEntry);
    }
}

// 文件日志处理器
public class FileLogHandler extends LogHandler {
    @Override
    protected boolean canHandle(LogEntry logEntry) {
        return logEntry.getLevel().ordinal() >= LogLevel.WARN.ordinal();
    }
  
    @Override
    protected void processLog(LogEntry logEntry) {
        System.out.println("文件日志: " + logEntry);
    }
}

// 邮件日志处理器
public class EmailLogHandler extends LogHandler {
    @Override
    protected boolean canHandle(LogEntry logEntry) {
        return logEntry.getLevel() == LogLevel.ERROR;
    }
  
    @Override
    protected void processLog(LogEntry logEntry) {
        System.out.println("邮件日志: " + logEntry);
    }
}

// 使用示例
public class LogChainDemo {
    public static void main(String[] args) {
        // 创建日志处理链
        LogHandler consoleHandler = new ConsoleLogHandler();
        LogHandler fileHandler = new FileLogHandler();
        LogHandler emailHandler = new EmailLogHandler();
      
        consoleHandler.setNext(fileHandler);
        fileHandler.setNext(emailHandler);
      
        // 处理日志
        LogEntry infoLog = new LogEntry(LogLevel.INFO, "系统启动");
        LogEntry warnLog = new LogEntry(LogLevel.WARN, "内存不足");
        LogEntry errorLog = new LogEntry(LogLevel.ERROR, "数据库连接失败");
      
        consoleHandler.handleLog(infoLog);
        consoleHandler.handleLog(warnLog);
        consoleHandler.handleLog(errorLog);
    }
}

3. 订单处理链

java 复制代码
// 订单处理器
public abstract class OrderHandler {
    protected OrderHandler nextHandler;
  
    public void setNext(OrderHandler nextHandler) {
        this.nextHandler = nextHandler;
    }
  
    public void processOrder(Order order) {
        if (canHandle(order)) {
            handleOrder(order);
        }
      
        if (nextHandler != null) {
            nextHandler.processOrder(order);
        }
    }
  
    protected abstract boolean canHandle(Order order);
    protected abstract void handleOrder(Order order);
}

// 库存验证处理器
public class InventoryHandler extends OrderHandler {
    @Override
    protected boolean canHandle(Order order) {
        return true; // 所有订单都需要验证库存
    }
  
    @Override
    protected void handleOrder(Order order) {
        if (order.getItems().stream().allMatch(item -> item.getStock() >= item.getQuantity())) {
            System.out.println("库存验证通过: " + order.getId());
        } else {
            System.out.println("库存不足: " + order.getId());
            order.setStatus(OrderStatus.CANCELLED);
        }
    }
}

// 支付处理处理器
public class PaymentHandler extends OrderHandler {
    @Override
    protected boolean canHandle(Order order) {
        return order.getStatus() != OrderStatus.CANCELLED;
    }
  
    @Override
    protected void handleOrder(Order order) {
        if (order.getPaymentMethod().isValid()) {
            System.out.println("支付处理成功: " + order.getId());
            order.setStatus(OrderStatus.PAID);
        } else {
            System.out.println("支付处理失败: " + order.getId());
            order.setStatus(OrderStatus.PAYMENT_FAILED);
        }
    }
}

// 发货处理处理器
public class ShippingHandler extends OrderHandler {
    @Override
    protected boolean canHandle(Order order) {
        return order.getStatus() == OrderStatus.PAID;
    }
  
    @Override
    protected void handleOrder(Order order) {
        System.out.println("开始发货: " + order.getId());
        order.setStatus(OrderStatus.SHIPPED);
    }
}

// 使用示例
public class OrderChainDemo {
    public static void main(String[] args) {
        // 创建订单处理链
        OrderHandler inventoryHandler = new InventoryHandler();
        OrderHandler paymentHandler = new PaymentHandler();
        OrderHandler shippingHandler = new ShippingHandler();
      
        inventoryHandler.setNext(paymentHandler);
        paymentHandler.setNext(shippingHandler);
      
        // 创建订单
        Order order = new Order("ORDER001", Arrays.asList(
            new OrderItem("ITEM001", 2, 10),
            new OrderItem("ITEM002", 1, 20)
        ), new PaymentMethod("CARD", "1234567890"));
      
        // 处理订单
        inventoryHandler.processOrder(order);
        System.out.println("订单状态: " + order.getStatus());
    }
}

面试高频点

面试知识点思维导图

责任链模式面试点 基本概念 实现方式 重难点 Spring应用 设计原则 实际应用 解耦发送者和接收者 动态链式处理 灵活配置 单一职责 Handler抽象处理者 ConcreteHandler具体处理者 Client客户端 Request请求类 责任链构建管理 终止条件设置 性能优化 异常处理 HandlerInterceptor FilterChain SecurityFilterChain AOP切面链 单一职责 开闭原则 依赖倒置 接口隔离 权限验证链 日志处理链 订单处理链 异常处理链

1. 责任链模式的基本概念

问题:什么是责任链模式?

答案要点:

  • 多个对象都有机会处理请求,避免请求发送者和接收者之间的耦合
  • 将这些对象连成一条链,沿着链传递请求
  • 属于行为型设计模式
  • 直到有一个对象处理请求为止
问题:责任链模式有哪些角色?

答案要点:

  • Handler(抽象处理者):定义处理请求的接口,实现后继链
  • ConcreteHandler(具体处理者):处理它所负责的请求,可访问它的后继者
  • Client(客户端):向链上的具体处理者对象提交请求

2. 实现方式相关

问题:如何实现责任链模式?

答案要点:

java 复制代码
// 1. 定义抽象处理者
public abstract class Handler {
    protected Handler nextHandler;
  
    public void setNext(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
  
    public abstract void handleRequest(Request request);
}

// 2. 实现具体处理者
public class ConcreteHandler extends Handler {
    @Override
    public void handleRequest(Request request) {
        if (canHandle(request)) {
            // 处理请求
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
  
    protected abstract boolean canHandle(Request request);
}

3. 重难点问题

问题:如何设置责任链的终止条件?

答案要点:

  • 检查下一个处理者:如果nextHandler为null,则链结束
  • 处理结果控制:根据处理结果决定是否继续传递
  • 异常处理:异常情况下可以终止链
  • 业务逻辑控制:根据业务需求设置终止条件
问题:责任链模式的性能如何优化?

答案要点:

java 复制代码
// 1. 缓存处理结果
public class CachedHandler extends Handler {
    private final Map<String, Boolean> cache = new ConcurrentHashMap<>();
  
    @Override
    public void handleRequest(Request request) {
        String key = generateKey(request);
        Boolean canHandle = cache.computeIfAbsent(key, k -> canHandle(request));
      
        if (canHandle) {
            // 处理请求
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 2. 并行处理
public class ParallelHandler extends Handler {
    private final ExecutorService executor = Executors.newFixedThreadPool(10);
  
    @Override
    public void handleRequest(Request request) {
        if (canHandle(request)) {
            executor.submit(() -> processRequest(request));
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

4. Spring中的应用

问题:Spring中如何使用责任链模式?

答案要点:

java 复制代码
// 1. HandlerInterceptor链
public class CustomInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 预处理逻辑
        return true;
    }
  
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        // 后处理逻辑
    }
}

// 2. Filter链
public class CustomFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 处理逻辑
        chain.doFilter(request, response);
    }
}

5. 设计原则相关

问题:责任链模式体现了哪些设计原则?

答案要点:

  • 单一职责:每个处理者只负责处理自己能处理的请求
  • 开闭原则:可以添加新的处理者而不修改现有代码
  • 依赖倒置:依赖抽象而不是具体实现
  • 接口隔离:客户端只依赖需要的接口

6. 实际应用场景

问题:责任链模式适用于哪些场景?

答案要点:

  • 权限验证:多级权限验证
  • 日志处理:多级日志处理
  • 订单处理:订单处理流程
  • 异常处理:多级异常处理
  • 请求处理:Web请求处理链
  • 数据验证:多级数据验证

使用总结

责任链模式的优势

  1. 解耦:请求发送者和接收者解耦
  2. 灵活配置:可以动态添加、删除、修改处理者
  3. 单一职责:每个处理者只负责自己的职责
  4. 可扩展性:易于添加新的处理者

责任链模式的缺点

  1. 性能问题:链式调用可能影响性能
  2. 调试困难:链式调用使调试变得困难
  3. 循环依赖:可能出现循环依赖问题
  4. 内存开销:链式调用占用额外内存

使用建议

  1. 简单场景:只用于简单的处理场景
  2. 性能考虑:注意链式调用的性能影响
  3. 异常处理:做好异常处理,避免链中断
  4. 测试覆盖:确保每个处理者都有测试覆盖

最佳实践

  1. 明确职责:每个处理者职责明确
  2. 异常处理:做好异常处理机制
  3. 性能优化:考虑缓存和并行处理
  4. 文档注释:为每个处理者添加详细注释
  5. 单元测试:为每个处理者编写单元测试

与其他模式的对比

  1. 与装饰器模式:责任链模式是链式处理,装饰器模式是包装处理
  2. 与策略模式:责任链模式是链式选择,策略模式是单一选择
  3. 与命令模式:责任链模式是处理请求,命令模式是封装请求

责任链模式是一种有用的行为型设计模式,特别适用于需要多级处理、权限验证、日志处理等场景。通过合理使用责任链模式,可以大大提高系统的灵活性和可维护性。

相关推荐
爱读源码的大都督3 小时前
2000字源码分析,聊聊Spring的扫描机制底层到底是如何实现的?
java·后端·spring
维尔切3 小时前
Apache Tomcat 部署与配置
java·linux·运维·tomcat·apache
对不起初见i3 小时前
MyBatis-Plus 全方位深度指南:从入门到精通
java·数据库·mybatis
橙-极纪元3 小时前
windows系统使用sdkman管理java的jdk版本,WSL和Git Bash哪个更能方便管理jdk版本
java·windows·sdkman
再睡亿分钟!3 小时前
思考:客户端负载均衡和服务器负载均衡有什么区别?
java·开发语言·微服务·负载均衡
一个程序员(●—●)3 小时前
设计模式——结构型模式(下)
设计模式
骑士雄师3 小时前
设计模式面试之单例模式常问知识点
java·面试题
JavaGuide3 小时前
小厂 Java 面试,难度怎么样?
java·后端
new_daimond3 小时前
设计模式-迭代器模式详解
设计模式·迭代器模式