本文為敏捷軟件開發(fā) - 原則、模式與實踐系列的一部分。
本文對應原書第16章
介紹
本節(jié)講述了兩個強制對象單一性的模式。這兩個模式有著非常不同的“代價/收益”權衡。在大多數(shù)情況下,它們的實時代價遠低于它們的表達力帶來的收益。
SINGLETON模式
public class Singleton {
private static Singleton theInstance = null;
private Singleton() {}
public static Singleton Instance() {
if (theInstance == null)
theInstance = new Singleton();
return theInstance;
}
}
上面是一個典型的有點瑕疵的SINGLETON實現(xiàn)
SINGLETON模式的好處
跨平臺:使用合適的中間件(例如,RMI),可以把SINGLETON模式擴展為跨多個JVM和多個計算機工作。
適用于任何類:只需把一個類的構造函數(shù)變成私有的,并且在其中增加相應的靜態(tài)函數(shù)和變量,就可以把這個類變?yōu)镾INGLETON。
可以透過派生創(chuàng)建:給定一個類,可以創(chuàng)建它的一個SINGLETON子類。
延遲求值:如果SINGLETON從未使用過,那么就不會創(chuàng)建它。
SINGLETON模式的代價
摧毀方法未定義:沒有好的辦法去摧毀一個SINGLETON,或者解除其職責。
不能繼承:從SINGLETON類派生出來的類并不是SINGLETON。如果要使其成為SINGLETON,必須要增加所需的靜態(tài)函數(shù)和變量。
效率問題:每次調用Instance方法都會執(zhí)行if語句。就大多數(shù)調用而言,if語句是多余的。
不透明性:SINGLETON的使用者知道它們正在使用一個SINGLETON,因為它們必須要調用Instance方法。
MONOSTATE模式
public class Monostate {
private static int itsX;
public Monostate() {}
public void setX(int x) {
itsX = x;
}
public int getX() {
return itsX;
}
}
MONOSTATE模式的好處
透明性:使用MONOSTATE對象和使用常規(guī)對象沒有什么區(qū)別。使用者不需要知道對象是MONOSTATE。
可派生性:MONOSTATE的派生類都是MONOSTATE。事實上,MONOSTATE的所有派生類都是同一個MONOSTATE的一部分。它們共享相同的靜態(tài)變量。
多態(tài)性:由于MONOSTATE的方法不是靜態(tài)的,所以可以在派生類中覆寫它們。因此,不同的派生類可以基于同樣的靜態(tài)變量表現(xiàn)出不同的行為。
MONOSTATE模式的代價
不可轉換性:不能透過派生將常規(guī)類轉換為MONOSTATE類。
效率問題:因為MONOSTATE是真正的對象,所以會導致許多的創(chuàng)建和摧毀開銷。
內存占用:即使從未使用MONOSTATE,它的變量也要占據(jù)內存空間。
平臺局限性:MONOSTATE不能跨多個JVM或者多個平臺工作。
結論
常常會有必要強制要求某個特定對象只能具有單一實例。本章展示了兩種非常不同的技術。SINGLETON模式使用私有構造函數(shù),一個靜態(tài)變量,以及一個靜態(tài)方法對實例化進行控制和限制。MONOSTATE模式只是簡單地把對象的所有變量變成靜態(tài)的。
如果希望透過派生去約束一個現(xiàn)存類,并且不介意它的所有調用者都必須要調用instance()方法來獲取訪問權,那么SINGLETON是合適的。如果希望類的單一性本質對使用者透明,或者希望使用單一對象的多態(tài)派生類,那么MONOSTATE是最適合的。
完整內容請查看敏捷軟件開發(fā) - 原則、模式與實踐系列