設計模式大概算是過了一遍了,但總體來說還不是很清楚,因此想在這裏全面的總結一下。
因爲之前學設計模式的時候是用C++寫的,在這裏就不再用C++再寫一遍了,所以本體系中的所有設計模式都將會以java代碼實現,有興趣的讀者可以自行用C++實現。
OK,話不多說,先從單例模式開始。
單例模式是最簡單的設計模式之一,這種設計模式是一種創建型的模式,提供了創建對象的最佳方式。
單例模式顧名思義就是一個類只允許創建一個實例,因此它只涉及到一個單一的類,並且這個類要完成自己創建自己的實例的工作,並保證能且只能創建一個實例。這個類還需要提供一個訪問這個實例的方法。
接下來我們分析一下單例模式的多種實現方式。(以下代碼均爲Java實現,若讀者有興趣可自行用C++實現)
一、懶漢形式(延遲加載)
public class Singleton{
private static Singleton singleton;//定義一個未初始化的私有靜態對象,外部不可訪問
//構造私有,保證外部不可創建實例
private Singleton() {
}
//提供公有方法獲取實例
public synchronized static Single newInstance() {
if (singleton== null) {
singleton= new Singleton();//如果singleton爲空就爲其創建實例
}
return singleton;//將創建好的實例返回
}
}
懶漢形式是標準的單例實現形式,它的延遲加載體現在newInstance方法裏的判斷,方法加了synchronized關鍵字可以避免多線程問題,但會影響程序性能。
二、餓漢形式(貪婪加載)
public class Singleton {
private static Singleton singleton= new Singleton();//直接創建私有靜態實例
//構造方法私有保證外部不可創建實例
private singleton() {
}
public static Singleton newInstance() {
return singleton;//將創建好的實例返回
}
}
在單例對象聲明的時候就直接初始化對象,可以避免多線程問題,但是如果對象初始化比較複雜,會導致程序初始化緩慢。
三、雙重鎖檢查
public class Singleton {
private volatile static Singleton singleton;
private Singleton() {
}
public static Singleton newInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
這個是懶漢形式的加強版,將synchronized關鍵字移到了newInstance方法裏面,同時將singleton對象加上volatile關鍵字,這種方式既可以避免多線程問題,又不會降低程序的性能。但volatile關鍵字也有一些性能問題,不建議大量使用。
四、Lazy initialization holder class
public class Singleton {
private static class SingletonHolder {
private static Singleton singleton = new Singleton();
}
private Singleton() {
}
public static Singleton newInstance() {
return SingletonHolder.singleton;
}
}
這裏創建了一個內部靜態類,通過內部類的機制使得單例對象可以延遲加載,同時內部類相當於是外部類的靜態部分,所以可以通過jvm來保證其線程安全。這種形式比較推薦。
五、枚舉
public enum Singleton {
singleton
}
單因素的枚舉類已經實現了單例,這種方法更加簡單。