14.设计模式-CHAIN OF RESPONSIBILITY(职责链)

一、模式定义与核心价值

责任链模式是一种行为型设计模式,其核心目标是通过链式结构解耦请求发送者与处理者,允许多个对象按顺序处理同一请求,直到某个对象决定处理或请求传递至链尾。该模式通过动态构建处理链路实现以下核心价值:

  1. 解耦请求与处理:客户端无需知道请求由谁处理,处理者仅关注自身职责。
  2. 动态扩展性:运行时灵活增删处理节点,支持业务规则变更。
  3. 单一职责原则:每个处理者仅处理其职责范围内的请求。

典型应用场景

  • 多级审批流程(如请假、采购审批)
  • 请求过滤与验证(如数据校验、权限控制)
  • 框架中间件(如Spring Security过滤器链、Servlet Filter)

二、模式组成与UML类图

核心角色
  1. 抽象处理者(Handler)
    • 定义处理请求的接口(如handleRequest()),维护指向下一个处理者的引用。
  1. 具体处理者(Concrete Handler)
    • 实现请求处理逻辑,若无法处理则传递给下一个处理者。
  1. 客户端(Client)
    • 构建责任链,并向链头提交请求。
UML类图
classDiagram
    class Handler {
        <<interface>>
        +setNext(Handler)
        +handleRequest(Request)
    }

    class ConcreteHandlerA {
        +handleRequest(Request)
    }

    class ConcreteHandlerB {
        +handleRequest(Request)
    }

    class Client {
        +buildChain()
    }

    Handler <|-- ConcreteHandlerA
    Handler <|-- ConcreteHandlerB
    Client --> Handler
    ConcreteHandlerA --> Handler : next
    ConcreteHandlerB --> Handler : next


三、代码实现示例

场景:实现请假审批流程(组长、CTO、CEO三级审批)

1. 抽象处理者
public abstract class Approver {
    protected Approver nextApprover;

    public void setNextApprover(Approver next) {
        this.nextApprover = next;
    }

    public abstract void handleRequest(LeaveRequest request);
}
2. 具体处理者
// 组长审批(处理≤3天请假)
public class TeamLeader extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 3) {
            System.out.println("组长批准" + request.getDays() + "天请假");
        } else if (nextApprover != null) {
            nextApprover.handleRequest(request);
        }
    }
}

// CTO审批(处理≤7天请假)
public class CTO extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        if (request.getDays() <= 7) {
            System.out.println("CTO批准" + request.getDays() + "天请假");
        } else if (nextApprover != null) {
            nextApprover.handleRequest(request);
        }
    }
}

// CEO审批(处理所有请假)
public class CEO extends Approver {
    @Override
    public void handleRequest(LeaveRequest request) {
        System.out.println("CEO批准" + request.getDays() + "天请假");
    }
}
3. 客户端调用
public class Client {
    public static void main(String[] args) {
        Approver teamLeader = new TeamLeader();
        Approver cto = new CTO();
        Approver ceo = new CEO();

        // 构建责任链
        teamLeader.setNextApprover(cto);
        cto.setNextApprover(ceo);

        // 提交请求
        teamLeader.handleRequest(new LeaveRequest(5));  // CTO处理
        teamLeader.handleRequest(new LeaveRequest(10)); // CEO处理
    }
}

四、工业级源码应用

  1. Spring Security过滤器链
    • 通过FilterChainProxy串联多个安全过滤器(如UsernamePasswordAuthenticationFilterBasicAuthenticationFilter),按顺序处理HTTP请求的安全校验。
  1. Servlet Filter机制
    • 请求通过配置的过滤器链(如日志、编码转换、权限校验),每个Filter决定是否传递给下一个过滤器。
  1. Netty的ChannelPipeline
    • 网络事件由ChannelHandler链处理(如解码、业务逻辑、编码),支持动态增删处理器。
  1. Java日志框架
    • Logback的Logger层级结构,日志事件从子Logger向根Logger逐级传递,匹配对应级别处理。

五、模式优劣与最佳实践

优势

  • 高扩展性:新增处理者无需修改现有代码(如添加新的审批角色)。
  • 灵活配置:动态调整处理链顺序(如调整权限校验顺序)。

局限性

  • 调试困难:长链可能导致请求路径不直观(需结合日志追踪)。
  • 性能损耗:链过长时请求传递可能影响性能(需控制链长度或缓存处理结果)。

实践建议

  1. 设置默认处理:避免请求未被处理(如返回统一错误响应)。
  2. 链长度控制:复杂场景拆分为子链(如分拆验证链与业务链)。

总结

责任链模式通过链式传递动态解耦,在Spring、Netty等框架中展现出强大的灵活性。其设计精髓在于职责分离动态扩展,开发者需重点把控链长控制与调试优化,使其成为复杂流程管理的利器

posted @ 2025-04-12 10:51  雾里看花的少年  阅读(37)  评论(0)    收藏  举报