設計模式之創建模式----單例模式

單例模式確保一個類只有一個實例,且自行實例化並向整個系統提供這個實例。

單例模式特點:

  • 單例類只能有一個實例
  • 單例類必須自己創建自己的實例
  • 單例類必須給其它對象提供這個實例

單例模式中單例類實現方式:

餓漢式實現

package com.create.single;
/**
 * 
 * 餓漢式單例
 * @date 2013-11-26
 */
public class Singleton {
	private final static Singleton singleton = new Singleton();
	
	private Singleton(){
		
	}
	
	public static Singleton getInstance(){
		return singleton;
	}
}

懶漢式實現

package com.create.single;
/**
 * 
 * 懶漢式單例創建
 * @date 2013-11-26
 */
public class LazySingleton {
	private static LazySingleton singleton;
	
	private LazySingleton(){
		
	}
	
	synchronized public static LazySingleton getInstance(){
		if(singleton==null){
			singleton = new LazySingleton();
		}
		return singleton;
	}
}

登記式實現

package com.create.single;

import java.util.HashMap;
import java.util.Map;

/**
 * 登記式單例類
 * 該種方式實現克服餓漢式與懶漢式單例類實現方式不能被繼承的缺點
 * @date 2013-11-26
 */
public class RegSingleton {
	private static Map<String,RegSingleton> reg = new HashMap<String, RegSingleton>();
	
	static{
		RegSingleton singleton = new RegSingleton();
		reg.put(singleton.getClass().getName(), singleton);
	}
	
	protected RegSingleton(){
		
	}
	
	public static RegSingleton getInstance(String name){
		if(name==null){
			name = "com.create.single.RegSingleton";
		}
		if(reg.get(name)==null){
			try {
				Object obj = Class.forName(name).newInstance();
				reg.put(name, (RegSingleton)obj);
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		return reg.get(name);
	}
}
package com.create.single;
/**
 * 
 * 登記式實現子類
 * @date 2013-11-26
 */
public class RegSingletonChild extends RegSingleton{
	public RegSingletonChild(){
		
	}
	
	public static RegSingletonChild getInstance(){
		return (RegSingletonChild)RegSingleton.getInstance("com.create.single.RegSingletonChild");
	}
}
通過以上的實現方式可以看出,餓漢式與懶漢式實現構造函數都是私有的,該類不能夠被繼承;但是餓漢式實現是靜態方式實例化,但從資源角度來看,餓漢式稍微差些,從反應時間和效率來看比懶漢式要好。登記式實現克服單例類不能被繼承的缺點。

單例類的狀態

(1)一個單例類是可以有狀態的,有狀態的單例類也可以是可變的單例對象。比如一個單例可以有int屬性,當然單例也可以有個聚集屬性,可以存儲多個狀態
(2)單例類也可以沒有狀態,僅作爲工具性函數。

注:多個JVM的分佈式系統與多個類加載器是不適合有狀態的單例的。

建議:使用惡漢式單例模式或者靜態工廠同步的懶漢式單例模式已經滿足需求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章