CoR 模式 (第一種)
CoR(Chain of Responsibility) 即職責鏈設計模式:使多個對象都有機會處理請求(Request),從而避免請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理他爲止。
職責鏈設計模式 大概有三個角色:
(1)請求(Request):封裝請求信息
(2)處理器(Handler):處理請求(Request),一個具體處理器一般只處理一種請 求,如果它不能處理傳遞過來的請求,那麼它就把該請求傳遞給職責鏈中的下一個處理器(後繼處理器 successor)。
(3)客戶端(Client):發送請求
定義不再多說,直接看實現。下面是一個傳統的CoR實現:
1,代表抽象請求的接口(Request)
public interface Request{
//......
}
2,實現Request接口的實現類,HelpRequest,PrintRequest,SaveRequest
假設有一個文本編輯器,用戶界面上有三個按鈕 Help,Print 和 Save
HelpRequest 代表 當用戶點擊 Help 按鈕時產生的 幫助請求,
PrintRequest 代表 當用戶點擊 Print 按鈕時產生的 打印請求,
SaveRequest 代表當用戶點擊 Save 按鈕時產生的 保存請求。
//幫助請求
public class HelpRequest implements Request{
//......
}
//打印請求
public class PrintRequest implements Request{
//......
}
//保存請求
public class SaveRequest implements Request{
//......
}
3,代表抽象處理器的接口Handler:
public interface Handler{
void handleRequest(Request request);
}
4,實現處理器接口的實現類 HelpHandler,PrintHandler,SaveHandler:
HelpHandler 處理 幫助請求(HelpRequest)
public class HelpHandler implements Handler{
//後繼處理器
private Handler successor;
public HelpHandler(Handler successor){this.successor = successor;}
public void handleRequest(Request request) {
if(request instanceof HelpRequest){
System.out.println("HelpHandler handle " +request.getClass().getSimpleName());
// handle request
}else{
System.out.println("PrintHandler can't handle "+request.getClass().getSimpleName());
if(successor != null)
successor.handleRequest(request);
}
}
}
PrintHandler 處理 打印請求(PrintRequest)
public class PrintHandler implements Handler{
//後繼處理器
private Handler successor;
public PrintHandler(Handler successor){this.successor = successor;}
public void handleRequest(Request request) {
if(request instanceof PrintRequest){
System.out.println("PrintHandler handle "+request.getClass().getSimpleName());
// handle request
}else{
System.out.println("PrintHandler can't handle "+request.getClass().getSimpleName());
if(successor != null)
successor.handleRequest(request);
}
}
}
SaveHandler處理 保存請求(SaveRequest)
public class SaveHandler implements Handler{
//後繼處理器
private Handler successor;
public SaveHandler(Handler successor){this.successor = successor;}
public void handleRequest(Request request) {
if(request instanceof SaveRequest){
System.out.println("SaveHandler handle "+request.getClass().getSimpleName());
// handle request
}else{
System.out.println("SaveHandler can't handle "+request.getClass().getSimpleName());
if(successor != null)
successor.handleRequest(request);
}
}
}
5,客戶端 Client 類
public class Client{
public static void main(String[] args){
Handler handler1 = new HelpHandler(null);
Handler handler2 = new PrintHandler(handler1);
Handler handler3 = new SaveHandler(handler2);
handler3.handleRequest(new HelpRequest());
handler3.handleRequest(new PrintRequest());
handler3.handleRequest(new SaveRequest());
}
}
運行 Client 類 輸出如下:
SaveHandler can't handle HelpRequest
PrintHandler can't handle HelpRequest
HelpHandler handle HelpRequest
SaveHandler can't handle PrintRequest
PrintHandler handle PrintRequest
SaveHandler handle SaveRequest
-----------------------------------------------------
用抽象類也可以,不過要把 handleRequest 中
(1)這個處理器是否能處理這個請求
和
(2)處理相應的請求
這兩個功能分離出來,定義成抽象方法供子類(具體處理器)實現
public abstract class AbstractHandler implements Handler {
protected Handler successor;
public AbstractHandler(Handler successor) {
this.successor = successor;
}
//定義爲final,不能被子類繼承
public final void handleRequest(Request request) {
if (canHandleRequest(request)) {
handleRequestMyself(request);
} else {
if (successor != null)
successor.handleRequest(request);
}
}
//這個處理器能否處理整個請求
protected abstract boolean canHandleRequest(Request request);
//處理相應的請求
protected abstract void handleRequestMyself(Request request);
}
CoR 模式 (第二種)
CoR(Chain of Responsibility) 職責鏈設計模式
討論了傳統的CoR實現:
但我感覺 讓 每個處理器都持有後繼處理器的引用,會增加處理器之間的耦合度.
下面是我的一些想法 和 具體實現:
(1)處理器 不持有 後繼處理器的引用,引入一個新的角色 處理器容器(HandlerContainer ),由容器管理每個處理器,並且這個處理器容器 也是一個處理器(實現了Handler 接口),他的處理能力是容器裏所有處理器的處理能力的和。
(2)一個處理器如果不能處理傳遞過來的請求,則拋出一個(CanNotHandleRequestException )異常,
如果管理這個處理器的容器接受到這個異常,則將請求傳遞給容器中的下一個處理器。如果容器中的所有處理器都不能處理這個請求,則由容器拋出一個(CanNotHandleRequestException )異常。
實現:與傳統CoR相比,處理器接口(Handler )不變,請求接口(Request )和實現類不變。
1,增加CanNotHandleRequestException 異常類,當處理器不能處理傳遞過來的請求時就拋出這個異常。
public class CanNotHandleRequestException extends Exception{
private static final long serialVersionUID = 1L;
}
2,增加處理器容器類(HandlerContainer ),處理器容器類也實現了處理器接口,他的處理能力是容器裏所有處理器的處理能力的和。
public class HandlerContainer implements Handler{
private List<Handler> handlers;
public HandlerContainer(){
handlers = new ArrayList<Handler>();
}
public boolean add(Handler handler){
return this.handlers.add(handler);
}
public boolean remove(Handler handler){
return this.handlers.remove(handler);
}
public void handleRequest(Request request) throws CanNotHandleRequestException{
int length = this.handlers.size();
for(int i = 0 ; i < length ; i++){
Handler handler = handlers.get(i);
try {
handler.handleRequest(request);
break;
} catch (CanNotHandleRequestException e) {
/*
* 如果處理器容器裏的所有處理器都不能處理該請求,
* 則由容器拋出 CanNotHandleRequestException 異常。
*/
if(i == length-1) throw e;
}
}
}
}
3,實現處理器接口的實現類 HelpHandler ,PrintHandler ,SaveHandler
HelpHandler 處理 幫助請求(HelpRequest )
public class HelpHandler implements Handler{
public void handleRequest(Request request) throws CanNotHandleRequestException {
if(request instanceof HelpRequest){
System.out.println("HelpHandler handle "+request.getClass().getSimpleName());
}else
throw new CanNotHandleRequestException();
}
}
PrintHandler 處理 打印請求(PrintRequest )
public class PrintHandler implements Handler{
public void handleRequest(Request request) throws CanNotHandleRequestException{
if(request instanceof PrintRequest){
System.out.println("PrintHandler handle "+request.getClass().getSimpleName());
}else{
throw new CanNotHandleRequestException();
}
}
}
SaveHandler 處理保存請求(SaveRequest )
public class SaveHandler implements Handler{
public void handleRequest(Request request) throws CanNotHandleRequestException{
if(request instanceof SaveRequest){
System.out.println("SaveHandler handle "+request.getClass().getSimpleName());
}else{
throw new CanNotHandleRequestException();
}
}
}
4,客戶端 Client 類
public class Client {
public static void main(String[] args) throws CanNotHandleRequestException{
HandlerContainer Container1 = new HandlerContainer();
Container1.add(new HelpHandler());
HandlerContainer Container2 = new HandlerContainer();
Container2.add(new PrintHandler());
Container2.add(new SaveHandler());
Container1.add(Container2);
Container1.handleRequest(new HelpRequest());
Container1.handleRequest(new PrintRequest());
Container1.handleRequest(new SaveRequest());
}
}
運行Client 類,輸出如下
HelpHandler handle HelpRequest
PrintHandler handle PrintRequest
SaveHandler handle SaveRequest