CHARLIE SAYS

查理如是说
DATE 2026-08-24
THEME
SERIES / DESIGN_PATTERNS / P-110 · 设计模式

设计模式 016:责任链(Chain Of Responsibility)

责任链模式(Chain of responsibility pattern)可以为某个请求创建一个对象链,每个对象依序检查此请求并对其进行处理,或者将它传给链中的下一个对象。发送请求的客户不需要知道链上的细节,从而与具体处理者解耦。

意图

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。

类图

Handler 定义处理请求的接口,并且实现后继链(successor)。原文图片丢失,据文字重绘。

classDiagram
    class Handler {
        <<abstract>>
        #Handler successor
        +handleRequest(Request)
    }
    class ConcreteHandler1 {
        +handleRequest(Request)
    }
    class ConcreteHandler2 {
        +handleRequest(Request)
    }
    class Request {
        -RequestType type
        -String name
        +getType() RequestType
        +getName() String
    }
    Handler <|-- ConcreteHandler1
    Handler <|-- ConcreteHandler2
    Handler --> Handler : successor

实现

先定义请求和请求类型:

public class Request {
    private RequestType type;
    private String name;

    public Request(RequestType type, String name) {
        this.type = type;
        this.name = name;
    }

    public RequestType getType() {
        return type;
    }

    public String getName() {
        return name;
    }
}

public enum RequestType {
    type1, type2
}

Handler 定义处理请求的接口,并维护后继链:

public abstract class Handler {

    protected Handler successor;

    public Handler(Handler successor) {
        this.successor = successor;
    }

    protected abstract void handleRequest(Request request);
}

两个具体处理者:能处理就处理,否则传给下家:

public class ConcreteHandler1 extends Handler {

    public ConcreteHandler1(Handler successor) {
        super(successor);
    }

    @Override
    protected void handleRequest(Request request) {
        if (request.getType() == RequestType.type1) {
            System.out.println(request.getName() + " is handle by ConcreteHandler1");
            return;
        }
        if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

public class ConcreteHandler2 extends Handler {

    public ConcreteHandler2(Handler successor) {
        super(successor);
    }

    @Override
    protected void handleRequest(Request request) {
        if (request.getType() == RequestType.type2) {
            System.out.println(request.getName() + " is handle by ConcreteHandler2");
            return;
        }
        if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

客户端组装链并发起请求:

public class Client {

    public static void main(String[] args) {
        Handler handler1 = new ConcreteHandler1(null);
        Handler handler2 = new ConcreteHandler2(handler1);
        Request request1 = new Request(RequestType.type1, "request1");
        handler2.handleRequest(request1);
        Request request2 = new Request(RequestType.type2, "request2");
        handler2.handleRequest(request2);
    }
}

输出:

request1 is handle by ConcreteHandler1
request2 is handle by ConcreteHandler2

JDK 中的应用

  • java.util.logging.Logger#log()
  • Apache Commons Chain
  • javax.servlet.Filter#doFilter()

相关模式:与装饰器的对比

责任链与装饰器结构上很相似:两者都把对象串成一串,调用沿着链递归传递。区别在于意图——装饰器的每个节点都会执行并在转发前后附加行为,强调”给对象增加职责”;责任链的每个处理者可以自行决定处理请求还是传给下一个,强调”请求由谁处理”。

系列导航

← Angular 22+ 教程 16:Angular 组件 vs Web Components 目录 软件工程 016:精益企业:集成精益、敏捷、DevOps 等 →
← 返回文章列表