CoR 模式的兩種形式

CoR 模式 (第一種)

 

CoR(Chain of Responsibility) 即職責鏈設計模式:使多個對象都有機會處理請求(Request),從而避免請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理他爲止。

職責鏈設計模式 大概有三個角色:
1)請求(Request):封裝請求信息
2)處理器(Handler):處理請求(Request),一個具體處理器一般只處理一種請 求,如果它不能處理傳遞過來的請求,那麼它就把該請求傳遞給職責鏈中的下一個處理器(後繼處理器 successor)。
3)客戶端(Client):發送請求

定義不再多說,直接看實現。下面是一個傳統的CoR實現:

1
,代表抽象請求的接口(Request)

public interface Request{

    //......


2
,實現Request接口的實現類,HelpRequestPrintRequestSaveRequest
    假設有一個文本編輯器,用戶界面上有三個按鈕 HelpPrint 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,實現處理器接口的實現類 HelpHandlerPrintHandlerSaveHandler
  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

 

 

 

發佈了18 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章