天天看點

Java之路:單例設計模式(Singleton Pattern)

構造方法的私有化

一個方法可根據實際需要,将其設定為不同的通路權限——public(公有通路)、private(私有通路)或預設通路(即方法前沒有修飾符)。

同樣,構造方法也有public與private之分。如果構造方法被設為private,那麼其他類中就無法調用該構造方法。 換句話說,在本類之外,就不能通過new關鍵字調用該構造方法建立該類的執行個體化對象,構造方法被聲明為private類型則隻能在類内部通路。。

先來看一個例子:

public class Demo {
	private Demo() {}	// 私有構造
	public static void main(String[] args) {
		Demo dd = new Demo();	// 可以在本類中執行個體化
	}
}

class Test {
	Demo d = new Demo();	// 錯誤,在本類之外,不能通過new關鍵字調用私有構造方法建立該類的執行個體化對象。
}
           

再來看一個例子:

package com.xy.test3;

class Singleton {
	static Singleton instance = new Singleton();	// 執行個體化對象
	
	// 此時的類中不會再生成無參的什麼都不做的構造
	private Singleton() {}
	public void print() {
		System.out.println("Hello World!");
	}
}

public class SingletonPattern {
	public static void main(String[] args) {
		Singleton instance = null;	// 聲明對象
		instance = Singleton.instance;	// 執行個體化對象
		instance.print();
	}
}
           

【結果】

Java之路:單例設計模式(Singleton Pattern)
類之中的所有屬性隻有在調用構造方法執行個體化對象之後才會配置設定空間。

那麼現在外部無法調用Singleton類的構造方法,是以依靠外部是不可能的,那麼就必須從内部的instance定義上想辦法,有沒有一種方法可以讓Singleton在沒有執行個體化對象的時候就去操作instance呢?自然可以想到使用static定義。

可是針對于類之中所有定義的屬性都會有一個明确的要求,必須使用private封裝,那麼一旦封裝之後,如果此時還希望可以在沒有執行個體化對象的時候取得instance屬性,就必須利用static方法傳回。 如下:
package com.xy.test3;

class Singleton {
	private static Singleton instance = new Singleton();	// 執行個體化對象
	
	// 此時的類中不會再生成無參的什麼都不做的構造
	private Singleton() {}
	public void print() {
		System.out.println("Hello World!");
	}
	
	public static Singleton getInstance() {	// 利用靜态方法傳回對象執行個體
		return instance;
	}
}

public class SingletonPattern {
	public static void main(String[] args) {
		Singleton instance = null;	// 聲明對象
		instance = Singleton.getInstance();	// 執行個體化對象
		instance.print();
	}
}
           

【結果】

Java之路:單例設計模式(Singleton Pattern)

如果要想産生類的執行個體化對象,那麼一定要調用構造方法,如果把一個類的構造方法卡死了,那麼就表示外部無法調用此構造,就意味着外部無法産生執行個體化對象。

同時在類内部定義的本類執行個體化對象使用的是static定義,static的特點是在全局資料區之中儲存,是一個公共屬性,那麼這樣一來,不管在外部聲明了多少個對象,那麼實際上隻是取得了唯一的一個執行個體化對象,是以這樣的設計在設計模式上講稱為單例設計模式。 Java中的構造方法私有化就是為這種軟體設計模式而服務的。

但是以上的代碼編寫實際上也存在一個問題,既然現在希望表示隻有唯一的一個執行個體化對象,那麼為了避免内部的對象會被重複執行個體化,是以最好加上一個關鍵字final定義。如下:

public class TestSingleDemo {
	public static void main(String[]args) {
	/*聲明一個Person類的對象
	 *雖私有化Person類的構造方法,
	 *但可通過Person類公有接口獲得Person執行個體化對象
	 */
	  Person p;	/* 聲明一個Person類的對象p,但并未執行個體化,
	  			 * 僅是在棧記憶體中為對象引用p配置設定了空間存儲,
	  			 * p所指向的對象并不存在。
	  			 */

    p=Person.getPerson();
    System.out.println("姓名:"+p.name);
  }
}
class Person
{
   String name;
   /* 
    * 在類聲明了一個Person類的執行個體化對象,
    * 此對象是在Person類的内部執行個體化,是以可以調用私有構造方法。
    * 此對象被辨別為static類型,表示為一靜态屬性。
    * 另外,在聲明Person對象的時候還加上了一個final關鍵字,
    * 此關鍵字表示對象PERSON不能被重新執行個體化,表示該對象不可更改。
    */
   private static final Person PERSON=new Person();
   private Person()
   {
    name="kehr";
   }
   public static Person getPerson()
   {
    return PERSON;
   }
}
           

【結果】

Java之路:單例設計模式(Singleton Pattern)

【結果分析】

由于Person類構造方法是private,是以如 Person p = new Person () ;已經不再可行了。隻能通過“p = Person.getPerson();”來獲得執行個體。

而由于這個執行個體PERSON是static的,全局共享一個,是以無論在Person類的外部聲明多少個對象,使用多少個“p = Person.getPerson();”,最終得到的執行個體都是同一個。

也就是說,此類隻能産生一個執行個體對象。 這種做法就是上面提到的單态設計模式。

所謂設計模式也就是在大量的實踐中總結和理論化之後優選的代碼結構、程式設計風格以及解決問題的思考方式。