閱讀792 返回首頁    go 阿裏雲 go 技術社區[雲棲]


談NullObject模式

知道這個模式還是通過《重構》,這個模式的出現還是了為了解決代碼重複的壞味道。在項目中很經常見到類似下麵這樣的代碼:
if(prj.getProjectId==null)
    plan.setCost(
0.0);
else
    plan.setCost(prj.getCost());

   我們在很多地方有類似的檢查對象是否為null,如果為null,需要一個默認值等等這樣的場景。顯然,代碼重複是壞味道,怎麼消除這個壞味道呢?答案就是使用NullObject替代之,Null Object繼承原對象。
class NullProject extends Project{
   
public boolean isNull(){
      
return true;
   }
}
class Project{
   
private double cost;
   
private String projectId;
   dot.gif.
   
public boolean isNull(){
        
return false;
   }
}

那麼,原來的代碼可以改寫為:
if(prj.isNull())
    plan.setCost(
0.0);
else
    plan.setCost(prj.getCost());

    如果Null Object的引入僅僅是帶來這個好處,似乎沒有理由讓我們多敲這麼多鍵盤。問題的關鍵是類似上麵這樣的判斷也許出現在很多處,那麼有價值的技巧出現了,我們在NullObject覆寫getCost,提供缺省值:
class NullProject extends Project{
   
public boolean isNull(){
      
return true;
   }
   
public double getCost(){
      
return 0.0;      
   }
}
    因此,檢查對象是否為null的代碼可以去掉if...else了:
plan.setCost(prj.getCost());

    請注意,隻有那些大多數客戶端代碼都要求null object做出相同響應時,這樣的行為才有意義。比如我們這裏當工程id為null,很多地方要求費用就默認為0.0。 特殊的行為我們仍然使用isNull進行判斷。
    當然,另外在需要返回NullObject的地方,你應該創建一個null object以替代一般的對象,我們可以建立一個工廠方法:

class Project{
   
private double cost;
   
private String projectId;
   dot.gifdot.gif.
   
public boolean isNull(){
        
return false;
   }
   
public Project createNullProject(){
        
return new NullProject();
   }
}


   Null Object模式帶來的好處:減少了檢查對象是否為null的代碼重複,提高了代碼的可讀性,通常這些Null Object也可以為單元測試帶來簡便。

文章轉自莊周夢蝶  ,原文發布時間2007-07-31

最後更新:2017-05-17 16:01:34

  上一篇:go  sicp 習題3.6-3.8試解
  下一篇:go  sicp 3.1.1小節習題嚐試解答