创建型(5种) 工厂方法 抽象工厂模式 单例模式 建造者模式 原型模式
结构型(7种) 适配器模式 装饰器模式 代理模式 外观模式 桥接模式 组合模式 享元模式
行为型(11种) 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它将请求的发送者与接收者解耦,让多个接收者对象形成一条链,并沿着这条链传递请求,直到有一个接收者处理它为止。每个接收者都有权决定是否处理请求,或者将请求转发给链上的下一个接收者。
结构:
- Handler(处理者)接口/抽象类: 定义处理请求的接口,通常包含一个处理请求的方法(如
handleRequest()
),以及一个设置或获取下一个处理者的方法(如setNext()
和getNext()
)。- ConcreteHandler(具体处理者): 实现处理者接口,负责处理特定类型的请求。每个具体处理者在处理请求时,可以选择处理请求、拒绝处理(通常通过返回特定值或抛出异常表示)或将其转发给下一个处理者。
原理:
请求发起者只需将请求发送给链上的第一个处理者,后续的传递过程完全由链上的处理者自行决定。每个处理者检查请求是否符合其处理条件,若符合则处理并终止传递,否则将请求转发给下一个处理者。这样,请求的发送者无需关心请求如何被处理,处理的责任分散在链上的各个处理者中。
优缺点:
-
优点:
- 发送者与接收者解耦,增加系统的灵活性,易于扩展新的处理者或调整处理顺序。
- 便于实现请求的分发、过滤、路由等功能。
- 通过在链上动态地添加或删除处理者,可以改变系统的处理行为。
-
缺点:
- 链条过长可能导致请求处理的效率下降。
- 如果处理链的构造不合理,可能会导致请求得不到处理(例如,链中没有能够处理该请求的处理者)。
- 调试较为困难,因为请求的处理过程可能涉及多个处理者。
场景:
- 处理请求可能有多种方式或多种条件,需要在运行时动态确定。
- 不希望请求发送者与接收者之间存在紧密耦合。
- 需要对请求进行过滤、分发、路由等操作。
代码示例(以Java为例)
在责任链模式中,决定下一个处理者的责任通常由处理者自身承担。具体而言,每个处理者在处理请求时,可以根据请求的内容、自身的处理能力等因素,判断是否需要将请求传递给链上的下一个处理者。下面是一个Java实现的例子,展示了处理者如何决定下一个处理者:
// 处理者接口
public abstract class Handler {
protected Handler nextHandler;
public void setNext(Handler handler) {
this.nextHandler = handler;
}
public abstract void handleRequest(Request request);
}
// 具体处理者A
public class ConcreteHandlerA extends Handler {
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
// 处理请求...
System.out.println("ConcreteHandlerA handled the request.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("No suitable handler found for the request.");
}
}
private boolean canHandle(Request request) {
// 根据请求内容判断处理者A是否能处理该请求
// 这里仅作为示例,实际逻辑应根据业务需求实现
return request.getType().equals("TypeA") && request.getPriority() >= 5;
}
}
// 具体处理者B
public class ConcreteHandlerB extends Handler {
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
// 处理请求...
System.out.println("ConcreteHandlerB handled the request.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
} else {
System.out.println("No suitable handler found for the request.");
}
}
private boolean canHandle(Request request) {
// 根据请求内容判断处理者B是否能处理该请求
// 这里仅作为示例,实际逻辑应根据业务需求实现
return request.getType().equals("TypeB") && request.getPriority() <= 8;
}
}
// 请求类
public class Request {
private String type;
private int priority;
// ... 构造函数、getters、setters ...
}
// 使用示例
public class Client {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB); // 构建责任链
Request requestA = new Request("TypeA", 7); // 创建请求对象A
Request requestB = new Request("TypeB", 6); // 创建请求对象B
handlerA.handleRequest(requestA); // 发起请求A
handlerA.handleRequest(requestB); // 发起请求B
}
}
在这个例子中,ConcreteHandlerA
和 ConcreteHandlerB
分别实现了 canHandle()
方法,用于判断是否能处理给定的请求。在 handleRequest()
方法中,每个处理者首先检查自己是否能处理请求,如果可以,则处理请求并终止传递;否则,将请求传递给下一个处理者。这种设计使得每个处理者都能根据请求内容自主决定是否处理或传递请求,从而实现了责任链模式的核心思想。