責(zé)任鏈模式
責(zé)任鏈模式的優(yōu)缺點(diǎn)
責(zé)任鏈模式與if…else…相比,他的耦合性要低一些,因?yàn)樗褩l件判定都分散到了各個(gè)處理類中,并且這些處理類的優(yōu)先處理順序可以隨意設(shè)定。責(zé)任鏈模式也有缺點(diǎn),這與if…else…語句的缺點(diǎn)是一樣的,那就是在找到正確的處理類之前,所有的判定條件都要被執(zhí)行一遍,當(dāng)責(zé)任鏈比較長時(shí),性能問題比較嚴(yán)重。
責(zé)任鏈模式的適用場(chǎng)景
假如使用if…else…語句來組織一個(gè)責(zé)任鏈時(shí)感到力不從心,代碼看上去很糟糕時(shí),就可以使用責(zé)任鏈模式來進(jìn)行重構(gòu)。
示例
定義一個(gè)處理優(yōu)先級(jí)類Level
public class Level {
private int level = 0;
public Level(int level) {
this.level = level;
}
public boolean above(Level level) {
if (this.level >= level.level) {
return true;
}
return false;
}
}
模擬一個(gè)處理請(qǐng)求Request類,該類會(huì)包含有處理優(yōu)先級(jí)類,以提示后面的處理器
public class Request {
Level level;
public Request(Level level) {
this.level = level;
}
public Level getLevel() {
return level;
}
}
模擬響應(yīng)類Response
public class Response {
}
定義一個(gè)抽象的處理抽象類Handler,之所有使用抽象類而不是純接口在于抽象類可以包含一些默認(rèn)的實(shí)現(xiàn)方法,對(duì)于確定的處理過程我們可以將其寫到抽象類的具體實(shí)現(xiàn)中,而對(duì)于每個(gè)處理器都不一樣的,這里我們只定義一個(gè)抽象方法,由具體的實(shí)現(xiàn)類去做具體的特定實(shí)現(xiàn):
public abstract class Handler {
public final Response handleRequest(Request request, FilterChain chain) {
Response response = null;
if (this.getHandlerLevel().above(request.getLevel())) {
response = this.response(request);
} else {
chain.doFilter(request);
}
return response;
}
protected abstract Level getHandlerLevel();
public abstract Response response(Request request);
}
處理器1 ConcreteHandler1:
public class ConcreteHandler1 extends Handler{
@Override
protected Level getHandlerLevel() {
return new Level(1);
}
@Override
public Response response(Request request) {
System.out.println("-----請(qǐng)求由處理器1進(jìn)行處理-----");
return null;
}
}
處理器2 ConcreteHandler2:
public class ConcreteHandler2 extends Handler {
@Override
protected Level getHandlerLevel() {
return new Level(3);
}
@Override
public Response response(Request request) {
System.out.println("-----請(qǐng)求由處理器2進(jìn)行處理-----");
return null;
}
}
處理器3 ConcreteHandler3:
public class ConcreteHandler3 extends Handler{
@Override
protected Level getHandlerLevel() {
return new Level(5);
}
@Override
public Response response(Request request) {
System.out.println("-----請(qǐng)求由處理器3進(jìn)行處理-----");
return null;
}
}
接下來出場(chǎng)是最關(guān)鍵的串聯(lián)類FilterChain,通過它我們來串聯(lián)上面提到的各個(gè)Handler:
import org.springframework.util.CollectionUtils;
import java.util.List;
public class FilterChain {
private int pos = 0;
private List<Handler> handlerList;
public FilterChain(List<Handler> handlerList) {
this.handlerList = handlerList;
}
/**
* 洋蔥模型,處理后能夠返回
*
* @param request
* @return
*/
public Response doFilter(Request request) {
if (!CollectionUtils.isEmpty(handlerList) && pos < handlerList.size()) {
System.out.println(String.format("the %d time for processing", pos + 1));
return handlerList.get(pos++).handleRequest(request, this);
}
return null;
}
}
OK,接下來寫個(gè)單測(cè)試一下:
import com.netease.learn.designPattern.fliterChain.*;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
/**
* 責(zé)任鏈模式測(cè)試類
*/
public class FliterChainTest {
@Test
public void test() {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
List<Handler> handlerList = Arrays.asList(handler1, handler2, handler3);
FilterChain filterChain = new FilterChain(handlerList);
filterChain.doFilter(new Request(new Level(4)));
}
}
備注:
- 在實(shí)際的工程中,我們通常在Spring 的XML文件中去初始化各個(gè)chain,然后將他們的實(shí)例注入到FilterChain中。
輸出如下:
the 1 time for processing
the 2 time for processing
the 3 time for processing
-----請(qǐng)求由處理器3進(jìn)行處理-----