*责任链模式 (蛮重要)
Chain of Responsibility
定义:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until and object.
让一个以上的对象都有机会处理请求,避免了发送者和接收者之间的耦合关系。将这些接收对象都连成一条链,并沿着这条链传递请求,直到有对象处理它为止。
责任链的链是由多个Handler的实现类组成的。
处理者
处理者有三个职责,
- 定义处理请求的方法
handleMessage
,唯一的pubic方法 - 定义编排方法
setNext
设置下个处理者 - 定义具体处理者需要实现的2个方法:
- 定义自己能够处理的级别getHandlerLevel
- 定义具体的处理任务echo
通用代码:
//抽象处理者类
public abstract class Handler {
private Handler nextHandler;
public final Response handleMessage(Request request) {
Response response = null;
//判断是不是轮到自己处理
if(this.getHandlerLevel().equals(request.getRequestLevel())) {
response = this.echo(request);
} else {
//判断是否有下个处理者
if(this.nextHandler != null) {
response = this.nextHandler.handleMessage(request);
} else {
//没有合适的下个处理类,就业务自行处理
}
}
return response;
}
//设置下个处理者
public void setNextHandler(Handler _handler) {
this.nextHandler = _handler;
}
//每个处理者都有一个处理级别
protected abstract Level getHandlerLevel();
//每个处理者都必须实现处理任务
protected abstract Response echo(Request request);
}
//具体处理者类
public class ConcreteHandler1 extends Handler {
protected Respone echo(Request req) {
//完成处理逻辑
return null;
}
protected Level getHandlerLevel() {
//设置自己的处理的级别
return null;
}
}
//具体处理者类
public class ConcreteHandler2 extends Handler {
protected Respone echo(Request req) {
//完成处理逻辑
return null;
}
protected Level getHandlerLevel() {
//设置自己的处理的级别
return null;
}
}
//还有更多的处理类
....
//场景类
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
//责任链顺序 1 - 2 - 3
handler1.setNext(handler2);
handler2.setNext(handler3);
//提交请求(包含请求等级信息),返回结果
Respone respone = handler1.handlerMessgae(new Request());
}
实际场景应用中,应该有一个封装类对责任链进行封装来代替Client,返回责任链中的第一个Handler,这样简化调用,减少耦合.
优点:
-
减少处理者和请求者的耦合,请求者不需要知道具体是谁处理的,处理者也可以不用知道请求的全貌.
这些处理关系都是Handler来解决的.
缺点:
- 当责任链过长时,性能会较差
- 环节过长的话,调试也不方便
实践:
-
节点阈值: 基于以上缺点,要对节点的数量进行控制,一般做法时对Handler设置一个最大节点数,在
setNext
方法里进行判断是否超过阈值,超过则不允许创建该链. -
我觉得这个责任链在一定场景里可以很好的代替使用if else啦