这是我参与更文挑战的第9天,活动详情查看:更文挑战
责任链模式
责任链模式是行为型设计模式之一。责任链模式可以理解成单链表结构,每个节点连接着下一个子节点,每个节点支持拆开后重新连接,因此链式结构具备灵活性。这种结构同样适用在设计模式当中,每个节点可以当做是一个对象,每个对象具有处理业务逻辑的能力并且每个对象关联另一个对象。当有一个业务请求从这个链式结构头部开始传递,沿着这条路径依次往下走,根据每个对象处理业务逻辑的能力,当某个对象可以处理该业务请求时把该业务逻辑消费掉,请求也就到此为止,这样一个过程就是责任链模式了。
实现
责任链实现如下,定义一个抽象ACPU类,具备拥有另一个抽象类ACPU的能力。继承ACPU实现CPU1和CPU2,同时实现handleRequest方法处理业务能力。
假设电脑具有多核CPU工作能力,当一个业务逻辑请求输入从CPU1开始传递,当CPU1无法处理该请求时则调用成员对象cpu的handleRequest让它继续处理该业务逻辑,直到有能力的cpu去run这个业务事件。当然一个业务逻辑请求的传递并不一定要从cpu1开始,同样也可以直接调用cpu2处理方法,如果有能力去判断哪个cpu具备处理该事务的能力完全可以越级直接调用。
public abstract class ACPU{
private ACPU cpu;
public void setCPU(ACPU cpu) {
this.cpu = cpu;
}
public ACPU getCPU() {
return cpu;
}
public abstract void handleRequest(String request);
}
public CPU1 extends ACPU{
@override
public void handleRequest(String request){
if(request == "2"){
if(cpu != null)
cpu.handleRequest(request);
}else{
run();
}
}
}
public CPU2 extends ACPU{
@override
public void handleRequest(String request){
if(cpu != null){
....
}else{
run();
}
}
}
CPU1 cpu1 = new CPU1();
CPU2 cpu2 = new CPU2();
cpu1.setCPU(cpu2);
cpu1.handleRequest("2");
cpu1.handleRequest("1");
cpu2.handleRequest("1");
复制代码
实例
OkHttp开源库当中的拦截器就是采用责任链模式。
在interceptors拦截器集合中加入各种类型拦截器,最终传递到RealInterceptorChain。
Response getResponseWithInterceptorChain() throws IOException {
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
return chain.proceed(originalRequest);
}
复制代码
RealInterceptorChain是一个拦截器管理器,在遍历拦截器的过程中不断去创建RealInterceptorChain对象去递归处理request, 直至某一个拦截器能够处理该request为止。
public final class RealInterceptorChain implements Interceptor.Chain {
......
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
if (index >= interceptors.size()) throw new AssertionError();
calls++;
......
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
......
return response;
}
}
///Interceptor拦截器接口
public interface Interceptor {
/**
* 拦截Chain,并触发下一个拦截器的调用
* @param chain 被处理的对象
* @return
* @throws IOException
*/
Response intercept(Chain chain) throws IOException;
interface Chain {
//返回请求
Request request();
//对请求进行处理
Response proceed(Request request) throws IOException;
......
}
}
复制代码
总结
责任链模式似乎又是对if-else形式的优化,优点是从结构上理解其实是将请求者和处理者关系解耦,提高灵活性;缺点也显而易见当责任链的处理者越来越多,链式调用的深度就越大,对于整条链路的遍历反而成为性能影响的原因之一,尤其是对于递归调用函数的使用。