談NullObject模式
知道這個模式還是通過《重構》,這個模式的出現還是了為了解決代碼重複的壞味道。在項目中很經常見到類似下麵這樣的代碼:
if(prj.getProjectId==null)
plan.setCost(0.0);
else
plan.setCost(prj.getCost());
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;
.
public boolean isNull(){
return false;
}
}
public boolean isNull(){
return true;
}
}
class Project{
private double cost;
private String projectId;

public boolean isNull(){
return false;
}
}
那麼,原來的代碼可以改寫為:
if(prj.isNull())
plan.setCost(0.0);
else
plan.setCost(prj.getCost());
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了:public boolean isNull(){
return true;
}
public double getCost(){
return 0.0;
}
}
plan.setCost(prj.getCost());
請注意,隻有那些大多數客戶端代碼都要求null object做出相同響應時,這樣的行為才有意義。比如我們這裏當工程id為null,很多地方要求費用就默認為0.0。 特殊的行為我們仍然使用isNull進行判斷。
當然,另外在需要返回NullObject的地方,你應該創建一個null object以替代一般的對象,我們可以建立一個工廠方法:
class Project{
private double cost;
private String projectId;

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


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