淺識JAVA設計模式——單例設計模式

Codeagles發表於2018-07-10

版權宣告:本文為 Codeagles 原創文章,可以隨意轉載,但必須在明確位置註明出處!!!

###單例設計模式

  • 什麼是單例設計模式? 所謂的單例設計指的是一個類只允許產生一個例項化物件。 我們來看單例設計模式是如何一步一步演化過來的。

####Talk is cheap, show me the code.

public class SingletonTest {

	public static void main(String[] args) {
		Singleton s= null;
		s=new Singleton();
		s.print();
	}

}
class Singleton{
	public Singleton(){}
	public void print(){
		System.out.println("Hello World");
	}
}
複製程式碼

對於這段程式碼,很簡單都不陌生,就是建立Singleton類,然後在另一個類中去例項化物件呼叫print方法,最後輸出Hello World。原因是因為當我們在SingletonTest中例項化了物件的時候呼叫了Singleton類中的無參的構造方法,接下來結果就不足為奇了。

public class SingletonTest {
	
	public static void main(String[] args) {
		Singleton s= null;
		s=new Singleton();//報錯
		s.print();
	}

}
class Singleton{
	private Singleton(){}//私有構造方法
	public void print(){
		System.out.println("Hello World");
	}
}
複製程式碼

那麼對於上述程式碼,進行改造,將構造方法的public改為private,那麼上述程式碼就會報錯,因為例項化的時候,構造方法被私有,表示該類不能被外部進行例項化物件,那麼如何解決這個問題,我們繼續看改造程式碼。

public class SingletonTest {
	
	public static void main(String[] args) {
		Singleton s= null;
		s=Singleton.instance;//②
		s.print();
	}

}
class Singleton{

	static Singleton instance = new Singleton();//①
	private Singleton(){}//私有構造方法
	public void print(){
		System.out.println("Hello World");
	}
}
複製程式碼

為了解決外部不能例項化物件的問題,那麼就在內部進行例項化物件,加上Singleton instance = new Singleton();那麼就可以解決這個問題,但是在內部是解決了,外部依然無法呼叫print方法啊,因為外部沒有物件,所以我們想到用static關鍵字,例如①所示,然後在SingletonTest中如②直接類.物件來建立新物件,再去呼叫print方法,問題搞定了。

那麼新的問題來了,以上雖然取得了Singleton類的例項化物件,但是對於類中的屬性應該用private進行封裝,想要訪問封裝屬性知道需要提供getter方法,那麼我們需要在①的前面加上private static Singleton instance = new Singleton();不過此時訪問的是static屬性,並且這個類無法在外部進行例項化物件建立,所以再提供一個static方法,因為static方法不受例項化控制。那麼改造的程式碼如下:

public class SingletonTest {
	
	public static void main(String[] args) {
		public static void main(String[] args) {
		Singleton s= null;
		s=Singleton.getInstance();//獲取例項化物件
		//s1=Singleton.getInstance();//獲取例項化物件
		//s2=Singleton.getInstance();//獲取例項化物件
		s.print();
	}
	}

}
class Singleton{

	private static Singleton instance = new Singleton();//加上private
	//提供static方法,用來獲取例項化物件
	public static Singleton getInstance(){
		return instance;
	}
	private Singleton(){}//私有構造方法
	public void print(){
		System.out.println("Hello World");
	}
}
複製程式碼

對於上述程式碼,在Singleton類中,提供了獲取例項化物件的靜態方法,也將屬性進行了私有化,那麼在SingletonTest中無論獲取多少個物件,實際上都是同一個物件,因為類載入的時候已經例項化了一次物件,這就是單例設計模式。

###擴充套件 對於單例設計模式,還有兩種型別:

  • 餓漢式
  • 懶漢式

####餓漢式 既然是餓漢式,我們就要在整體之中,只能有一個例項化物件,所以一般在原基礎上還會為其增加final關鍵字。這個沒有什麼分析的問題。

class Singleton{

	private final static Singleton INSTANCE = new Singleton();//加上final
	//提供static方法,用來獲取例項化物件
	public static Singleton getInstance(){
		return INSTANCE;
	}
	private Singleton(){}//私有構造方法
	public void print(){
		System.out.println("Hello World");
	}
}
複製程式碼

對於程式碼改造就是一點,其他的都不變,這就是餓漢式。 ####懶漢式 所謂懶漢式,是指第一次去使用Singleton類物件的時候,才會為其進行例項化處理操作。

class Singleton{

	private static Singleton instance;//不需要再去例項化
	public static Singleton getInstance(){
		if(instance==null){//表示此時還沒有例項化物件
			instance=new Singleton();
		}
		return instance;
	}
	private	 Singleton(){}//私有構造方法
	public void print(){
		System.out.println("Hello World");
	}
}
複製程式碼

這就是懶漢式,當然這個設計模式在後續多執行緒等部分會有效能問題,以後我們在進行討論。

對於單例的使用場景,比如windows中的回收站就是一個例子,不管是在C,D,E盤那個碟符中,都會有一個隱藏的回收站資料夾,將檔案放入到該資料夾後,再回到桌面上開啟回收站發現檔案在裡面,說明不論在哪,整個系統只有一個回收站,這就是典型的單例設計。

以上就是單例設計模式,一步一步在最基礎的程式碼中,演化出來的。

相關文章