登記單式單例模式研究

zbw發表於2004-02-11
在《JAVA與模式》中,討論了一種登記單式的單例模式,目的是為了能夠繼承,我沒有太看明白書中所說的繼承是為了繼承“單例”的特性還是為了繼承那個能夠實現單例特性的Class的其他特性。反正在書裡的程式碼裡,子類的建構函式必須是public的,這樣的類當然可以被new一個新的例項,因此有不少問題。

我於是打算自己做個例子,目的如下:
1、單例的特性與一般物件的特性分開
2、需要單例的物件,都不能被new
3、不要有多餘的開銷。

在一般的例子中,建構函式要麼是public,要麼是private,其實他也可以是protected的。於是我在系統中建一個signlaton包,這個包裡只有一個類GetSignlaton可以透過getInstance()對外提供自己的例項,其他的物件,則需要透過這個GetSignlaton得到。

程式碼如下:

//管理單例類
package signlaton;
import java.util.Hashtable;
public class GetSignlaton {
	private static GetSignlaton gs;
	private static Hashtable ObjList;
	private GetSignlaton(){}
	public static GetSignlaton getInstance(){
		if(gs==null){
			gs=new GetSignlaton();
		}
		return gs;
	}
	public Object getObj(String name){
		if(ObjList==null){
			ObjList=new Hashtable();
		}
		if(ObjList.get(name)==null){
			try{
				ObjList.put(name,Class.forName("signlaton."+name).newInstance());
			} catch(Exception e){
			}
		}
		return ObjList.get(name);
	}
}

//某一個具體的單例類
package signlaton;
public class SignObj {
	private String t="";
	protected SignObj(){}
	public void setT(String v){
		t=v;
	}
	public String getT(){
		return t;
	}
}

//測試類
package test;
import signlaton.*;
public class SignTest {
	public static void main(String[] args) {
		GetSignlaton gs=GetSignlaton.getInstance();
		SignObj so=(SignObj)gs.getObj("SignObj");
		so.setT("123");
		System.out.println(so.getT());
		SignObj so2=(SignObj)gs.getObj("SignObj");
		so2.setT("1234");
		System.out.println(so.getT());
		System.out.println(so2.getT());
	}
}
<p class="indent">

相關文章