拦截器模式-业务场景应用

原 http://www.littlefisher.site/2019/05/17/拦截器模式-业务场景应用/

类图

该类图比较简陋,具体的可以参考网上关于拦截过滤器的设计模式类图

PS:拦截过滤器模式好像并不是23种设计模式中的一种,而是后来扩展出来的

具体的代码实现

下面这个接口,就是类图中的InteceptorChain,只不过ChainInteceptor的内部类,为了维护泛型

public interface Interceptor<T, R> {

    /**
     * 拦截器处理
     *
     * @param chain 调用链
     * @return 拦截器出参
     */
    R process(Chain<T, R> chain);

    interface Chain<T, R> {

        /**
         * 请求入参
         *
         * @return 请求入参
         */
        T request();

        /**
         * 链式调用
         *
         * @param request 入参
         * @return 出参
         */
        R proceed(T request);
    }
}

下面这个接口就是Call的接口定义

public interface Call<T, R> {

    /**
     * 请求入参
     *
     * @return 请求入参
     */
    T request();

    /**
     * 执行
     *
     * @return 执行
     */
    R execute();
}

下面开始描述实现类
Chain实现

public class DefaultChain
    implements Interceptor.Chain<Request, Response> {

    /** 当前执行到的拦截器的index */
    private final int index;
    /** 请求入参 */
    private final Request request;
    /** 拦截器 */
    private List<Interceptor> interceptors;

    public DefaultChain(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) {
        if (index >= interceptors.size()) {
            throw new IllegalArgumentException("index >= interceptors.size()");
        }
        Interceptor.Chain<Request, Response> next = new DefaultChain(
            interceptors, index + 1, request);
        Interceptor interceptor = interceptors.get(index);

        Response response = interceptor.process(next);
        if (response == null) {
            throw new NullPointerException("interceptor " + interceptor + " returned null");
        }
        return response;
    }
}

Call实现

public class DefaultCall implements Call<Request, Response> {

    private final Request originalRequest;

    private final List<Interceptor> interceptorList;

    public DefaultCall(Request originalRequest, List<Interceptor> interceptorList) {
        this.originalRequest = originalRequest;
        this.interceptorList = interceptorList;
    }

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

    @Override
    public Response execute() {
        DefaultChain chain = new DefaultChain(interceptorList, 0, originalRequest);
        return chain.proceed(originalRequest);
    }
}

Inteceptor实现

public class Demo1Interceptor implements Interceptor {

    @Override
    public Response process(Chain<Request, Response> chain) {
        Request request = chain.request();
        // do something
        return chain.proceed();
    }

}
public class Demo2Interceptor implements Interceptor {

    @Override
    public Response process(Chain<Request, Response> chain) {
        Request request = chain.request();
        // do something
        return chain.proceed();
    }

}

业务侧调用,下面的调用中,就会按照传入的拦截器的顺序进行执行

public class Demo {
    public static void main(String[] args) {
        Inteceptor inteceptor1 = new Demo1Interceptor();
        Inteceptor inteceptor2 = new Demo2Interceptor();
        Request request = new Request();
        Response response = new DefaultCall(request, Lists.newArrayList(inteceptor1, inteceptor2)).execute();
        System.out.println(response);
    }
}

后话

以上的代码,都是基于java直接使用的方式,但是在真正的业务代码中,可以融入Spring自动注入的方式,来做到最大的扩展性和单例使用

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值