最近,遇到這樣一個應用.在系統中需要大量的配置信息,為了不每次都找資料庫或者配置文件.需要一個生命周期和App一樣的容器(=靜態變數),但是在配置信息被修改時還需要去更新這個容器.
首先選用的是單實例模式.單實例模式中又可分為惡漢,懶漢,以及一種基於餓漢型的註冊型.
個人感覺懶漢型單例模式沒什麼,而餓漢型的更能體現java特點.然註冊行的可擴展性較強,個人感覺有點像
一個實例工廠.下面來一一列舉.
惡漢:
Java代碼
public class EagerSingleton { private static final EagerSingleton m_instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return m_instance; } } |
懶漢:
Java代碼
public class LazySingleton { private static LazySingleton m_instance = null; private LazySingleton() { } synchronized public static LazySingleton getInstance() { if (m_instance == null) { m_instance = new LazySingleton(); } return m_instance; } } |
註冊型:
Java代碼
public class RegSingleton { static private HashMap m_registry = new HashMap(); static { RegSingleton x = new RegSingleton(); m_registry.put(x.getClass().getName(), x); } protected RegSingleton() { } static public RegSingleton getInstance(String name) { if (name == null) { name = "name"; } if (m_registry.get(name) == null) { try { m_registry.put(name, Class.forName(name).newInstance()); } catch (Exception e) { System.out.println("Error happened."); } } return (RegSingleton) (m_registry.get(name)); } } |
Java代碼
public class RegSingletonChild extends RegSingleton { private RegSingletonChild() { } /** * 靜態工廠方法 */ static public RegSingletonChild getInstance() { return (RegSingletonChild) RegSingleton.getInstance("name"); } } |
由於在我們這個系統中各種配置信息較多,我個人感覺使用註冊型的單實例模式比較合適.(還能應付對配置信息變化的要求).然後就需要給我們的單實例模式添加更新的行為了.
Java代碼
public class ConfigClass { static private HashMap m_registry = new HashMap(); static { ConfigClass x = new ConfigClass(); m_registry.put(x.getClass().getName(), x); } /** * 保護的默認構造子 */ protected ConfigClass() { } /** * 靜態工廠方法,返還此類惟一的實例 */ static public ConfigClass getInstance(String name) { if (name == null) { name = "singleConfig.ConfigClass"; } if (m_registry.get(name) == null) { try { m_registry.put(name, Class.forName(name).newInstance()); } catch (Exception e) { System.out.println("Error happened."); } } return (ConfigClass) (m_registry.get(name)); } } |
Java代碼
public class ConfigImpl extends ConfigClass { private List properties = null; /** * @return the properties */ public List getProperties() { return properties; } private ConfigImpl() { initalProperties(); } public static ConfigImpl getInstance() { return (ConfigImpl) ConfigClass.getInstance("singleConfig.ok.ConfigImpl"); } /** * * @author xiaofeng.bai<BR> * <B>Time</B> : 2008-12-11 下午01:59:24 */ public void updateProperties() { ConfigImpl con = new ConfigImpl(); properties = con.getProperties(); } /** * @author xiaofeng.bai<BR> * <B>Time</B> : 2008-12-11 下午01:56:53 */ private void initalProperties() { // 初始化配置信息 } } |
呵呵終於完成了,但是現在發現一個問題很暈.我在ConfigImpl中的updateProperties()中有創建了一個ConfigImpl的實例,這樣能完成我對properties的更新嗎?
單實例顧名思義在一個JVM中只有一個實例,這樣是否可行呢?
[火星人 ] 可更新的註冊式的單實例模式已經有673次圍觀