1. 程式人生 > >設計模式學習筆記(十九)—Chain of Responsibility職責鏈模式

設計模式學習筆記(十九)—Chain of Responsibility職責鏈模式

轉貼自 http://www.blogjava.net/flustar/archive/2007/12/14/cor.html
Chain of Responsibility模式定義:
為了避免請求的傳送者和接收者之間的耦合關係,使多個接受物件都有機會處理請求。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。
我的理解:
在不止一個物件可以處理客戶端請求的時候,為了使每個物件都有處理請求的機會,把這些物件順序地串聯起來形成一個鏈,每個被串聯的物件都有一個指向下一個 物件的指標,當請求到來是,按照順序,先有第一個物件來處理這個請求,這個物件有兩個選擇:要麼處理,要麼把請求傳給下一個物件(每個物件都有這兩個選 擇),就這樣一直到有一個物件來處理這個請求為止,一旦有一個物件處理了這個請求就停止對請求的傳遞。當然也有可能到了物件鏈的最後,也沒有一個物件來處 理請求。我覺得這個與我們平常寫的if…else if…else…要完成的功能太相似了。以上所說的只是Chain of Responsibility的一種情況,有的書上叫它純職責鏈模式(我能處理就處理,不能處理才讓別人處理),它還有另一種情況也就是不純職責鏈模式 (我只處理我能處理的部分,處理不了的部分再讓別人來處理)。
Chain of Responsibility模式主要涉及兩個角色:
1) 抽象處理者角色(Handler):它定義了一個處理請求的介面。當然對於鏈子的不同實現,也可以在這個角色中實現後繼鏈。
2) 具體處理者角色(Concrete Handler):實現抽象角色中定義的介面,並處理它所負責的請求。如果不能處理則訪問它的後繼者。
由於這個模式的UML比較簡單,我就不再畫出來了。下面我舉個例子:一個純的和一個不純的。先來個純的:
現在的女孩子找男朋友基本上都有三個要求:有車、有房、有責任心,如果你這三樣都沒有,就險了。雖然我沒車、也沒房、但是我有責任心。^_^
class Boy{
 private boolean hasCar; //是否有車
 private boolean hasHouse; //是否有房
 private boolean hasResponsibility; //是否有責任心
 
 public Boy() {
 
 }
 public Boy(boolean hasCar, boolean hasHouse, boolean hasResponsibility) {
  this.hasCar = hasCar;
  this.hasHouse = hasHouse;
  this.hasResponsibility = hasResponsibility;
 }
 public boolean isHasCar() {
  return hasCar;
 }
 public void setHasCar(boolean hasCar) {
  this.hasCar = hasCar;
 }
 public boolean isHasHouse() {
  return hasHouse;
 }
 public void setHasHouse(boolean hasHouse) {
  this.hasHouse = hasHouse;
 }
 public boolean isHasResponsibility() {
  return hasResponsibility;
 }
 public void setHasResponsibility(boolean hasResponsibility) {
  this.hasResponsibility = hasResponsibility;
 }
 
 
}
interface Handler{
 public void handleRequest(Boy boy);
}
class CarHandler implements Handler{//檢查是否有車
 private Handler handler;

 public CarHandler(Handler handler) {
  this.handler = handler;
 }

 public Handler getHandler() {
  return handler;
 }

 public void setHandler(Handler handler) {
  this.handler = handler;
 }

 public void handleRequest(Boy boy) {
  if(boy.isHasCar()){
   System.out.println("呵呵,我有輛車");
  }else{
   System.out.println("我沒有車");
   handler.handleRequest(boy);
  }
  
 }
 
}
class HouseHandler implements Handler{ //檢查是否有房
 private Handler handler;

 public HouseHandler(Handler handler) {
  
  this.handler = handler;
 }

 public Handler getHandler() {
  return handler;
 }

 public void setHandler(Handler handler) {
  this.handler = handler;
 }

 public void handleRequest(Boy boy) {
  if(boy.isHasHouse()){
   System.out.println("沒想到吧,我還有房子");
  }else{
   System.out.println("我也沒有房");
   handler.handleRequest(boy);
  }
  
 }
 
}
class ResponsibilityHandler implements Handler{ //檢查是否有責任心
 private Handler handler;

 public ResponsibilityHandler(Handler handler) {
  this.handler = handler;
 }

 public Handler getHandler() {
  return handler;
 }

 public void setHandler(Handler handler) {
  this.handler = handler;
 }

 public void handleRequest(Boy boy) {
  if(boy.isHasResponsibility()){
   System.out.println("我只有一顆帶Responsibility的心");
  }else{
   System.out.println("更沒有責任心");
   handler.handleRequest(boy);
  }
  
 }
 
}
class Girl{
 public static void main(String[] args){
 Boy boy=new Boy(false,false,true);//這個boy沒有車,也沒有房,不過很有責任心
 Handler handler=new CarHandler(new HouseHandler(new ResponsibilityHandler(null)));//也可以使用setHanlder方法
 handler.handleRequest(boy);
 }
}
為了編這個例子,我死了好多腦細胞。。。。。。。。。。
下面再來個不純的:
為了讓減少腦細胞的死亡數量,這個例子我就不編了,用網上一位大俠所寫的。
這個例子模擬了汽車組裝的過程:假設一輛汽車從生產到出廠要經過以下四個過程:組裝車頭,車身,車尾,以及上色。
abstract class CarHandler {
    public static final int STEP_HANDLE_HEAD = 0;
    public static final int STEP_HANDLE_BODY = 0;
    public static final int STEP_HANDLE_TAIL = 0;
    public static final int STEP_HANDLE_COLOR = 3;
   
    protected CarHandler carHandler;

    public CarHandler setNextCarHandler(CarHandler carHandler) {
      this.carHandler = carHandler;
     
      return this.carHandler;
    }

    abstract public void handleCar(int lastStep);
}


class CarHeadHandler extends CarHandler {

    @Override
    public void handleCar(int lastStep) {
        if (STEP_HANDLE_HEAD <= lastStep) {
            System.out.println("Handle car's head.");
        }
               
        if (carHandler != null) {
            carHandler.handleCar(lastStep);
        }
    }
}

class CarBodyHandler extends CarHandler {

    @Override
    public void handleCar(int lastStep) {
        if (STEP_HANDLE_BODY <= lastStep) {
            System.out.println("Handle car's body.");
        }
       
        if (carHandler != null) {
            carHandler.handleCar(lastStep);
        }
    }
}

class CarTailHandler extends CarHandler {

    @Override
    public void handleCar(int lastStep) {
        if (STEP_HANDLE_TAIL <= lastStep) {
            System.out.println("Handle car's tail.");
        }
       
        if (carHandler != null) {
            carHandler.handleCar(lastStep);
        }
    }
}


class CarColorHandler extends CarHandler {

    @Override
    public void handleCar(int lastStep) {
        if (STEP_HANDLE_COLOR == lastStep) {
            System.out.println("Handle car's color.");
        }
       
       
        if (carHandler != null) {
            carHandler.handleCar(lastStep);
        }
    }
}
public class Client {

    public static void main(String[] args) {
        //工作流程1:先組裝車頭,然後是車身,車尾,最後是上色
        System.out.println("---workfolow1----");
        CarHandler carHandler1 = new CarHeadHandler();
        carHandler1.setNextCarHandler(
                new CarBodyHandler()).setNextCarHandler(
                        new CarTailHandler()).setNextCarHandler(
                                new CarColorHandler());
       
        carHandler1.handleCar(CarHandler.STEP_HANDLE_COLOR);
       
       
        //工作流程2:因為某種原因,我們需要先組裝車尾,然後是車身,車頭,最後是上色
        System.out.println("---workfolow2---");
        CarHandler carHandler2 = new CarTailHandler();
        carHandler2.setNextCarHandler(
                new CarBodyHandler()).setNextCarHandler(
                        new CarHeadHandler()).setNextCarHandler(
                                new CarColorHandler());
       
        carHandler2.handleCar(CarHandler.STEP_HANDLE_COLOR);
    }
}
模式的使用範圍:
1) 有多個的物件可以處理一個請求,哪個物件處理該請求執行時刻自動確定。
2) 你想在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。
3) 可處理一個請求的物件集合應被動態指定。
優缺點:
1) 責任的分擔。每個類只需要處理自己該處理的工作(不該處理的傳遞給下一個物件完成),明確各類的責任範圍,符合類的最小封裝原則。
2) 可以根據需要自由組合工作流程。如工作流程發生變化,可以通過重新分配物件鏈便可適應新的工作流程。
3) 類與類之間可以以鬆耦合的形式加以組織。
4) 責任鏈模式可能會帶來一些額外的效能損耗,因為它要從鏈子開頭開始遍歷。