| 職責(zé)鏈模式(Chain of Responsibility):使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。 適用場(chǎng)景: 1、有多個(gè)的對(duì)象可以處理一個(gè)請(qǐng)求,哪個(gè)對(duì)象處理該請(qǐng)求運(yùn)行時(shí)刻自動(dòng)確定; 2、在不明確指定接收者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求; 3、處理一個(gè)請(qǐng)求的對(duì)象集合應(yīng)被動(dòng)態(tài)指定。 通用類圖: 
 在大學(xué)里面當(dāng)班干部,時(shí)常要向上級(jí)申請(qǐng)各方面的東西。譬如申請(qǐng)全班外出秋游,普通同學(xué)將申請(qǐng)表交給班長(zhǎng),班長(zhǎng)簽字之后交給輔導(dǎo)員,輔導(dǎo)員批準(zhǔn)之后上交到主任辦公室…就是這樣,一個(gè)請(qǐng)求(這里是一份申請(qǐng)表)有時(shí)候需要經(jīng)過(guò)好幾個(gè)級(jí)別的處理者(這里是輔導(dǎo)員、主任)的審查才能夠最終被確定可行與否。 在這里表現(xiàn)出來(lái)的是一個(gè)職責(zé)鏈,即不同的處理者對(duì)同一個(gè)請(qǐng)求可能擔(dān)負(fù)著不同的處理方式、權(quán)限,但是我們希望這個(gè)請(qǐng)求必須到達(dá)最終拍板的處理者(否則秋游就沒(méi)戲了)。這種關(guān)系就很適合使用職責(zé)鏈模式了。 類圖結(jié)構(gòu)如下:  代碼實(shí)現(xiàn)如下:       interface Levels {      public static final int LEVEL_01 = 1;      public static final int LEVEL_02 = 2;      public static final int LEVEL_03 = 3;  } 
    abstract class AbstractRequest {      private String content = null;       public AbstractRequest(String content) {          this.content = content;      }       public String getContent() {          return this.content;      }            public abstract int getRequestLevel();  } 
    class Request01 extends AbstractRequest {      public Request01(String content) {          super(content);      }       @Override     public int getRequestLevel() {          return Levels.LEVEL_01;      }  }    class Request02 extends AbstractRequest {      public Request02(String content) {          super(content);      }       @Override     public int getRequestLevel() {          return Levels.LEVEL_02;      }  }    class Request03 extends AbstractRequest {      public Request03(String content) {          super(content);      }       @Override     public int getRequestLevel() {          return Levels.LEVEL_03;      }  } 
    abstract class AbstractHandler {           private AbstractHandler nextHandler = null;            public final void handleRequest(AbstractRequest request) {                    if (this.getHandlerLevel() == request.getRequestLevel()) {              this.handle(request);          } else {                           if (this.nextHandler != null) {                  System.out.println("當(dāng)前 處理者-0" + this.getHandlerLevel()                          + " 不足以處理 請(qǐng)求-0" + request.getRequestLevel());                                                     this.nextHandler.handleRequest(request);              } else {                  System.out.println("職責(zé)鏈上的所有處理者都不能勝任該請(qǐng)求...");              }          }      }            public void setNextHandler(AbstractHandler nextHandler) {          this.nextHandler = nextHandler;      }            protected abstract int getHandlerLevel();            protected abstract void handle(AbstractRequest request);  } 
    class Handler01 extends AbstractHandler {      @Override     protected int getHandlerLevel() {          return Levels.LEVEL_01;      }       @Override     protected void handle(AbstractRequest request) {          System.out.println("處理者-01 處理 " + request.getContent() + "\n");      }  }    class Handler02 extends AbstractHandler {      @Override     protected int getHandlerLevel() {          return Levels.LEVEL_02;      }       @Override     protected void handle(AbstractRequest request) {          System.out.println("處理者-02 處理 " + request.getContent()+ "\n");      }  }    class Handler03 extends AbstractHandler {      @Override     protected int getHandlerLevel() {          return Levels.LEVEL_03;      }       @Override     protected void handle(AbstractRequest request) {          System.out.println("處理者-03 處理 " + request.getContent()+ "\n");      }  } 
    public class Client {      public static void main(String[] args) {                   AbstractHandler handler01 = new Handler01();          AbstractHandler handler02 = new Handler02();          AbstractHandler handler03 = new Handler03();                    handler01.setNextHandler(handler02);          handler02.setNextHandler(handler03);                    AbstractRequest request01 = new Request01("請(qǐng)求-01");          AbstractRequest request02 = new Request02("請(qǐng)求-02");          AbstractRequest request03 = new Request03("請(qǐng)求-03");                             handler01.handleRequest(request01);          handler01.handleRequest(request02);          handler01.handleRequest(request03);      }  } 
 測(cè)試結(jié)果: 處理者-01 處理 請(qǐng)求-01  當(dāng)前 處理者-01 不足以處理 請(qǐng)求-02 處理者-02 處理 請(qǐng)求-02  當(dāng)前 處理者-01 不足以處理 請(qǐng)求-03 當(dāng)前 處理者-02 不足以處理 請(qǐng)求-03 處理者-03 處理 請(qǐng)求-03 
 在上面抽象處理者 AbstractHandler 類的 handleRequest() 方法中,被 protected 修飾,并且該方法中調(diào)用了兩個(gè)必須被子類覆蓋實(shí)現(xiàn)的抽象方法,這里是使用了模板方法模式(Template Mehtod)。其實(shí)在這里,抽象父類的 handleRequest() 具備了請(qǐng)求傳遞的功能,即對(duì)某些請(qǐng)求不能處理時(shí),馬上提交到下一結(jié)點(diǎn)(處理者)中,而每個(gè)具體的處理者僅僅完成了具體的處理邏輯,其他的都不用理。   記得第一次看到職責(zé)鏈模式的時(shí)候,我很驚訝于它能夠把我們平時(shí)在代碼中的 if..else.. 的語(yǔ)句塊變成這樣靈活、適應(yīng)變化。例如:如果現(xiàn)在輔導(dǎo)員請(qǐng)長(zhǎng)假了,但我們的秋游還是要爭(zhēng)取申請(qǐng)成功呀,那么我們?cè)?Client 類中可以不要?jiǎng)?chuàng)建 handler02,即不要將該處理者組裝到職責(zé)鏈中。這樣子處理比 if..else..好多了。或者說(shuō),突然來(lái)了個(gè)愛(ài)管閑事的領(lǐng)導(dǎo),那么我照樣可以將其組裝到職責(zé)鏈中。   關(guān)于上面使用場(chǎng)景中提到的3個(gè)點(diǎn): 1、處理者在運(yùn)行時(shí)動(dòng)態(tài)確定其實(shí)是我們?cè)?Client 中組裝的鏈所引起的,因?yàn)榫唧w的職責(zé)邏輯就在鏈中一一對(duì)應(yīng)起來(lái); 2、因?yàn)椴淮_定請(qǐng)求的具體處理者是誰(shuí),所以我們把所有可能的處理者組裝成一條鏈,在遍歷的過(guò)程中就相當(dāng)于向每個(gè)處理者都提交了這個(gè)請(qǐng)求,等待其審查。并且在審查過(guò)程中,即使不是最終處理者,也可以進(jìn)行一些請(qǐng)求的“包裝”操作(這種功能類似于裝飾者模式),例如上面例子中的簽名批準(zhǔn); 3、處理者集合的動(dòng)態(tài)指定跟上面的第1、2點(diǎn)類似,即在 Client 類中創(chuàng)建了所有可能的處理者。   不足之處: 1、對(duì)于每一個(gè)請(qǐng)求都需要遍歷職責(zé)鏈,性能是個(gè)問(wèn)題; 2、抽象處理者 AbstractHandler 類中的 handleRequest() 方法中使用了遞歸,??臻g的大小也是個(gè)問(wèn)題。  個(gè)人看法: 職責(zé)鏈模式對(duì)于請(qǐng)求的處理是不知道最終處理者是誰(shuí),所以是運(yùn)行動(dòng)態(tài)尋找并指定;而命令模式中對(duì)于命令的處理時(shí)在創(chuàng)建命令是已經(jīng)顯式或隱式綁定了接收者。 |