23种设计模式-java

Chain of responsibility-责任链模式

2018-06-08  本文已影响9人  oneWeekOneTopic

解决问题

它主要解决的问题是“递归、循环”问题或者大量的if-else 问题。通过定义不通的receiver,并在运行时决定receiver的执行顺序。它带来的一个好处是:receiver逻辑耦合(可以分不同的场景划分receiver逻辑), 代码结构清晰。

应用场景

信息或者请求 需要经过大量的if-else处理(转换成由多个receiver中的其中一个进行处理);

信息或请求 需要进行流水线处理(即需要经过层层加工)

原理图(UML)

image

Handler:持有nextHander对象,以便交下一个链条;并持有一个handle方法来处理请求

Receiver:实现Handler接口,并实现具体的处理逻辑

Sender:生成具有一定处理顺序的链条,并启动链条的头部来处理请求。

示例

这里我们举一个场景:去饭店吃饭,首先我们要向点餐员点菜、然后点餐员将菜名报给厨师、厨师做完菜之后将菜端到我们面前。

public abstract class Handler {

    protected Handler nextHandler;
    public abstract void handle();

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
}
public class OrderTaker extends Handler {

    @Override
    public void handle() {
        System.out.println("请客人点餐");
        System.out.println("客人点餐完成");
        if (this.nextHandler != null) {
            nextHandler.handle();
        } else {
            System.out.println("厨师下班了。。。");
        }
    }
}

public class Cooker extends Handler {

    @Override
    public void handle() {
        System.out.println("为客人做菜");
        System.out.println("做菜完成");
        if (this.nextHandler != null) {
            nextHandler.handle();
        } else {
            System.out.println("该招送餐员了。。。。");
        }
    }
}

public class Deliver extends Handler {

    @Override
    public void handle() {
        System.out.println("将菜送到客人面前");
    }
}

public class Manager {
    public static void main(String[] args) {
        // 组织结构
        OrderTaker orderTaker = new OrderTaker();
        Cooker cooker = new Cooker();
        Deliver deliver = new Deliver();
        orderTaker.setNextHandler(cooker);
        cooker.setNextHandler(deliver);
        // 来一个客人
        orderTaker.handle();
    }
}

下面的这种形式是一个变种,但其在各种基本组件中应用则更为广泛

spring -filter/interceptor都是采用的该模式,下面贴一部分OkHtpp中的对请求的处理源码。该示例参考:https://blog.csdn.net/yxhuang2008/article/details/72566928

public interface  Interceptor {

    Response intercept(Chain chain) throws IOException;


    interface Chain{
        Request request();

        Response proceed(Request request) throws IOException;

    }
}

public class BridgeInterceptor implements Interceptor{

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request userRequest = chain.request();

        Response networkResponse = chain.proceed(userRequest);

        System.out.println("BridgeInterceptor intercept");

        return networkResponse;
    }
}

public class CacheInterceptor implements Interceptor{

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        Response response = chain.proceed(request);

        System.out.println("CacheInterceptor intercept");
        return response;
    }
}


public class ConnectInterceptor implements Interceptor{

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        Response response = new Response();

        System.out.println("ConnectInterceptor intercept");
        return response;
    }

}


public class RealInterceptorChain implements Interceptor.Chain{

    private final List<Interceptor> interceptors;
    private final int index;
    private final Request request;
    private int calls;

    public RealInterceptorChain(List<Interceptor> interceptors, int index, Request request) {
        this.interceptors = interceptors;
        this.index = index;
        this.request = request;
    }

    @Override
    public Request request() {
        return request;
    }

    @Override
    public Response proceed(Request request) throws IOException {
        if (index >= interceptors.size()) {
            throw new AssertionError();
        }

        calls++;

        // Call the next interceptor in the chain.
        RealInterceptorChain next = new RealInterceptorChain(interceptors, index + 1, request);
        Interceptor interceptor = interceptors.get(index);
        Response response = interceptor.intercept(next);

        // Confirm that the next interceptor made its required call to  chain.proceed().
        if (index + 1 < interceptors.size() && next.calls != 1) {
            throw new IllegalStateException("network interceptor " + interceptor
                    + " must call proceed() exactly once");
        }

        // Confirm that the intercepted response isn't null.
        if (response == null) {
            throw new NullPointerException("interceptor " + interceptor  + " returned null");
        }
        return response;
    }
}

public class TempClient {

    public static void main(String[] args) throws IOException {

        List<Interceptor> interceptors = new ArrayList<Interceptor>();
        interceptors.add(new BridgeInterceptor());
        interceptors.add(new CacheInterceptor());
        interceptors.add(new ConnectInterceptor());

        Request request = new Request();
        Interceptor.Chain chain = new RealInterceptorChain(interceptors, 0, request);
        chain.proceed(request);

        /**
         *  执行结果, 倒序
         *   ConnectInterceptor intercept
         *   CacheInterceptor intercept
         *   BridgeInterceptor intercept
         */
    }

}

参考

上一篇下一篇

猜你喜欢

热点阅读