模式定義
責(zé)任鏈模式(Chain of Responsibility Pattern) 使多個對象都有機會處理請求伴澄,從而避免請求的發(fā)送者和接受者直接的耦合關(guān)系。將這些對象連成一條鏈袋马,沿著這條鏈傳遞該請求,直到有一個對象處理它為止秸应。
責(zé)任鏈模式強調(diào)的是每一個對象及其對下家的引用來組成一條鏈虑凛,利用這種方式將發(fā)送者和接收者解耦
模式結(jié)構(gòu)
主要角色:
- 抽象處理者(Handler)角色 :定義一個請求的接口。如果需要可以定義個一個方法用來設(shè)定和返回下家對象的引用软啼。
- 具體處理者(ConcreteHandler)角色 :如果可以處理就處理請求桑谍,如果不能處理,就把請求傳給下家祸挪,讓下家處理霉囚。也就是說它處理自己能處理的請求且可以訪問它的下家。
示例
熟悉JavaWeb開發(fā)的同學(xué)匕积,一定對Servlet規(guī)范 中的Filter 使用非常熟悉,其實它內(nèi)部就是使用責(zé)任鏈模式(FilterChain)實現(xiàn)的榜跌,本文將揭曉Filter的實現(xiàn)原理闪唆。
Filter 接口定義如下:
public interface Filter {
void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws Exception;
}
DemoFilter 代碼如下:
public class DemoFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
System.out.println("filter execute...");
chain.doFilter(request, response);
}
}
當(dāng)我們在Filter 的 doFilter方法處理完自己的業(yè)務(wù)邏輯后,老司機都會告訴你需要調(diào)用chain.doFilter(request, response);
將請求轉(zhuǎn)到下一個Filter中钓葫,那FilterChain.doFilter(request, response)
到底是怎么實現(xiàn)的呢悄蕾?
FilterChain
public interface FilterChain {
void doFilter(ServletRequest request, ServletResponse response) throws Exception;
}
FilterChain 接口定義很簡單,接下來看看它的實現(xiàn)類FilterChainImpl 础浮,代碼如下:
import java.util.List;
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
* @date 2017-02-18 14:02
*/
public class FilterChainImpl implements FilterChain {
private int pos; //當(dāng)前位置
private List<Filter> filters;
private HttpHandler next;
public FilterChainImpl(List<Filter> filters, HttpHandler next) {
this.filters = filters;
this.next = next;
this.pos = 0;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws Exception {
if (pos >= filters.size()) {
this.next.handleRequest(request, response);
} else {
Filter filter = filters.get(pos++);
filter.doFilter(request, response, this);
}
}
}
最后帆调,我們可以模擬一下Filter調(diào)用:
import java.util.ArrayList;
import java.util.List;
/**
* ${DESCRIPTION}
*
* @author Ricky Fung
* @date 2017-02-18 14:14
*/
public class FilterChainDemo {
public static void main(String[] args) {
List<Filter> filters = new ArrayList<>();
for(int i=1; i<=5;i++){
filters.add(new DemoFilter("Filter_"+i));
}
ServletRequest request = new ServletRequest();
ServletResponse response = new ServletResponse();
HttpHandler httpHandler = new HttpHandler(); //http請求處理器
FilterChain filterChain = new FilterChainImpl(filters, httpHandler);
try {
filterChain.doFilter(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}