前面討論了創(chuàng)建型模式浴捆、結(jié)構(gòu)型模式选泻,今天我們來討論一下行為型模式滔金。責(zé)任鏈模式,就是我們討論的第一種行為型模式科阎。責(zé)任鏈模式具體不容易說出來蝌矛,但是如果看一看責(zé)任鏈模式的實(shí)際例子就很容易明白了。最典型的例子就是Java EE Servlet中的過濾器入撒,以鏈?zhǔn)椒绞綄φ埱筮M(jìn)行過濾了茅逮。當(dāng)我們遇到類似需求的時(shí)候,也可以使用責(zé)任鏈模式來解決判哥。
下面我們來模擬一下Java Servlet中的Filter献雅。首先,需要請求和響應(yīng)的接口和實(shí)現(xiàn)塌计。這兩個(gè)接口都很簡單挺身。
//請求
public interface Request {
String getMessage();
}
class RequestImpl implements Request{
private String msg;
public RequestImpl(String msg) {
this.msg = msg;
}
@Override
public String getMessage() {
return msg;
}
}
//響應(yīng)
public interface Response {
String getMessage();
}
class ResponseImpl implements Response {
private String msg;
public ResponseImpl(String msg) {
this.msg = msg;
}
@Override
public String getMessage() {
return msg;
}
}
之后是過濾器的接口和實(shí)現(xiàn)。過濾器將會對請求和處理進(jìn)行處理和過濾锌仅。過濾器1和2是正常的過濾器章钾,過濾之后還會繼續(xù)調(diào)用鏈上的其它過濾器墙贱。而過濾器3則會直接阻斷鏈。
public interface Filter {
void doFilter(Request request, Response response, FilterChain chain);
}
class FilterImpl1 implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("In filter1: " + request.getMessage() + ":" + response.getMessage());
chain.doFilter(request, response);
}
}
class FilterImpl2 implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("In filter2: " + request.getMessage() + ":" + response.getMessage());
chain.doFilter(request, response);
}
}
class FilterImpl3 implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("In filter3: " + request.getMessage() + ":" + response.getMessage());
}
}
下面來實(shí)現(xiàn)責(zé)任鏈贱傀。責(zé)任鏈其實(shí)和很簡單惨撇,開始過濾之后,責(zé)任鏈就會不斷的調(diào)用鏈上的過濾器窍箍,直到某個(gè)過濾器判斷不需要繼續(xù)過濾(例如過濾器3)或者鏈到頭為止。為了讓這個(gè)鏈能夠復(fù)用祷蝌,我還添加了當(dāng)前調(diào)用鏈的標(biāo)記current剑令,標(biāo)記調(diào)用到哪里了,再到頭之后重新將current設(shè)置為0。
class FilterChain {
private List<Filter> filters;
private int current;
public FilterChain(List<Filter> filters) {
this.filters = filters;
current = 0;
}
void doFilter(Request request, Response response) {
if (current <= filters.size() - 1) {
Filter currentFilter = filters.get(current);
current++;
currentFilter.doFilter(request, response, this);
} else {
current = 0;
}
}
}
這樣一個(gè)責(zé)任鏈就完成了。我們來調(diào)用一下。
public void run() {
Filter filter1 = new FilterImpl1();
Filter filter2 = new FilterImpl2();
List<Filter> filters = new ArrayList<>();
filters.add(filter1);
filters.add(filter2);
FilterChain chain = new FilterChain(filters);
Request request = new RequestImpl("request1");
Response response = new ResponseImpl("response1");
chain.doFilter(request, response);
System.out.println();
filters.add(0,new FilterImpl3());
chain.doFilter(request, response);
}
結(jié)果應(yīng)該類似這樣。和我們的預(yù)期相同。
責(zé)任鏈模式
In filter1: request1:response1
In filter2: request1:response1
In filter3: request1:response1