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

类图

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

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

具体的代码实现

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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的接口定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface Call<T, R> {

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

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

 

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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实现

1
2
3
4
5
6
7
8
9
10
public class Demo1Interceptor implements Interceptor {

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

}

 

1
2
3
4
5
6
7
8
9
10
public class Demo2Interceptor implements Interceptor {

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

}

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

1
2
3
4
5
6
7
8
9
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自动注入的方式,来做到最大的扩展性和单例使用

posted @ 2019-07-31 15:52  qxwang  阅读(45)  评论(0)    收藏  举报