Chain of Responsibility定義:Chain of Responsibility(CoR) 是用一系列類(classes)試圖處理一個請求request,這些類之間是一個松散的耦合,唯一共同點是在他們之間傳遞request。也就是說,來了一個請求,A類先處理,如果沒有處理,就傳遞到B類處理,如果沒有處理,就傳遞到C類處理,就這樣象一個鏈條(chain)一樣傳遞下去。
雖然這一段是如何使用CoR,但是也是演示什麼是CoR。
有一個Handler接口:
public interface Handler{ public void handleRequest(); }
這是一個處理request的事例, 如果有多種request,比如 請求幫助 請求打印 或請求格式化:
◆ 最先想到的解決方案是:在接口中增加多個請求:
public interface Handler{ public void handleHelp(); public void handlePrint(); public void handleFormat(); }
具體是一段實現接口Handler代碼:
public class ConcreteHandler implements Handler{ private Handler successor; public ConcreteHandler(Handler successor){ this.successor=successor; } public void handleHelp(){ //具體處理請求Help的代碼 ... } public void handlePrint(){ //如果是print 轉去處理Print successor.handlePrint(); } public void handleFormat(){ //如果是Format 轉去處理format successor.handleFormat(); } }
一共有三個這樣的具體實現類,上面是處理help,還有處理Print 處理Format這大概是我們最常用的編程思路。
雖然思路簡單明了,但是有一個擴展問題,如果我們需要再增加一個請求request種類,需要修改接口及其每一個實現。
◆ 第二方案:將每種request都變成一個接口,因此我們有以下代碼 :
public interface HelpHandler{ public void handleHelp(); } public interface PrintHandler{ public void handlePrint(); } public interface FormatHandler{ public void handleFormat(); } public class ConcreteHandler implements HelpHandler,PrintHandler,FormatHandlet{ private HelpHandler helpSuccessor; private PrintHandler printSuccessor; private FormatHandler formatSuccessor; public ConcreteHandler(HelpHandler helpSuccessor,PrintHandler printSuccessor,FormatHandler formatSuccessor) { this.helpSuccessor=helpSuccessor; this.printSuccessor=printSuccessor; this.formatSuccessor=formatSuccessor; } public void handleHelp(){ ....... } public void handlePrint(){this.printSuccessor=printSuccessor;} public void handleFormat(){this.formatSuccessor=formatSuccessor;} }
這個辦法在增加新的請求request情況下,只是節省了接口的修改量,接口實現ConcreteHandler還需要修改。而且代碼顯然不簡單美麗。
◆ 解決方案3:在Handler接口中只使用一個參數化方法:
public interface Handler{ public void handleRequest(String request); } 那麼Handler實現代碼如下: public class ConcreteHandler implements Handler{ private Handler successor; public ConcreteHandler(Handler successor){ this.successor=successor; } public void handleRequest(String request){ if (request.equals("Help")){ //這裡是處理Help的具體代碼 }else //傳遞到下一個 successor.handle(request); } } }
這裡先假設request是String類型,如果不是怎麼辦?當然我們可以創建一個專門類Request
◆ 最後解決方案:接口Handler的代碼如下:
public interface Handler{ public void handleRequest(Request request); } Request類的定義: public class Request{ private String type; public Request(String type){this.type=type;} public String getType(){return type;} public void execute(){ //request真正具體行為代碼 } }
那麼Handler實現代碼如下:
public class ConcreteHandler implements Handler{ private Handler successor; public ConcreteHandler(Handler successor){ this.successor=successor; } public void handleRequest(Request request){ if (request instanceof HelpRequest){ //這裡是處理Help的具體代碼 }else if (request instanceof PrintRequst){ request.execute(); }else //傳遞到下一個 successor.handle(request); } } }
這個解決方案就是CoR,在一個鏈上,都有相應職責的類,因此叫Chain of Responsibility。
擴展性差,因為在CoR中,一定要有一個統一的接口Handler.局限性就在這裡。