Posted on 2007-07-31 17:48
dennis 閱讀(5176)
評(píng)論(7) 編輯 收藏 所屬分類:
模式與架構(gòu)
知道這個(gè)模式還是通過(guò)《重構(gòu)》,這個(gè)模式的出現(xiàn)還是了為了解決代碼重復(fù)的壞味道。在項(xiàng)目中很經(jīng)常見(jiàn)到類似下面這樣的代碼:
if(prj.getProjectId==null)
plan.setCost(0.0);
else
plan.setCost(prj.getCost());
我們?cè)诤芏嗟胤接蓄愃频臋z查對(duì)象是否為null,如果為null,需要一個(gè)默認(rèn)值等等這樣的場(chǎng)景。顯然,代碼重復(fù)是壞味道,怎么消除這個(gè)壞味道呢?答案就是使用NullObject替代之,Null Object繼承原對(duì)象。
class NullProject extends Project{
public boolean isNull(){
return true;
}
}
class Project{
private double cost;
private String projectId;
.
public boolean isNull(){
return false;
}
}
那么,原來(lái)的代碼可以改寫為:
if(prj.isNull())
plan.setCost(0.0);
else
plan.setCost(prj.getCost());
如果Null Object的引入僅僅是帶來(lái)這個(gè)好處,似乎沒(méi)有理由讓我們多敲這么多鍵盤。問(wèn)題的關(guān)鍵是類似上面這樣的判斷也許出現(xiàn)在很多處,那么有價(jià)值的技巧出現(xiàn)了,我們?cè)贜ullObject覆寫getCost,提供缺省值:
class NullProject extends Project{
public boolean isNull(){
return true;
}
public double getCost(){
return 0.0;
}
}
因此,檢查對(duì)象是否為null的代碼可以去掉if...else了:
plan.setCost(prj.getCost());
請(qǐng)注意,只有那些大多數(shù)客戶端代碼都要求null object做出相同響應(yīng)時(shí),這樣的行為才有意義。比如我們這里當(dāng)工程id為null,很多地方要求費(fèi)用就默認(rèn)為0.0。
特殊的行為我們?nèi)匀皇褂胕sNull進(jìn)行判斷。
當(dāng)然,另外在需要返回NullObject的地方,你應(yīng)該創(chuàng)建一個(gè)null object以替代一般的對(duì)象,我們可以建立一個(gè)工廠方法:
class Project{
private double cost;
private String projectId;

.
public boolean isNull(){
return false;
}
public Project createNullProject(){
return new NullProject();
}
}
Null Object模式帶來(lái)的好處:減少了檢查對(duì)象是否為null的代碼重復(fù),提高了代碼的可讀性,通常這些Null Object也可以為單元測(cè)試帶來(lái)簡(jiǎn)便。