Posted on 2007-02-22 18:48
acooly 閱讀(426)
評論(0) 編輯 收藏 所屬分類:
Java開發 、
設計模式
??????單例模式(singleton)在很多系統中都比較常用。我用得最多的就是用來做緩存。最新重新學習設計模式,想整理一下開發中的一些經驗和資料上的講解以備以后查看。
Singleton模式要點
1.單例類在一個容器中只有一個實例。
2.單例類使用靜態方法自己提供向客戶端提供實例,自己擁有自己的引用。
3.必須向整個容器提供自己的實例。
單例類的狀態
1、無狀態單例類可以在多個容器或JVM中存在多個實例而正常運行,因為它是無狀態就意味是完全相同的拷貝,如系統內的通用工具方法類等;
2、有狀態的單例實例一般是可變的,比如提供表的為一KEY的單例類,一般不在多個容器或JVM中使用,除非建立特殊機制協調各個實例間的狀態。
單例類的種類
1、餓漢式和懶漢式
餓漢式和懶漢式單例非常相識,主要的區別在于餓漢式在聲明實例變量的時候就初始化實例,而懶漢式是在構造函數中通過判斷實例是否存在,在創建實例。
/**/
/*
?*?餓漢是單例類?Hungry?Singleton
?@author?ZhangPu
?Feb?22,?2007?7:34:50?PM
?
*/
public
?
class
?HungrySingleton?
{

????
/**?*/
/**
?聲明時候初始化?
*/
????
private
?
static
?HungrySingleton?hungrySingleton?
=
?
new
?HungrySingleton();

????
/**?*/
/**
?????*?私有構造
?????
*/
????
private
?HungrySingleton()
{}
????

????
/**?*/
/**
?????*?單例方法
?????*?
@return
?????
*/
????
public
?
static
?HungrySingleton?getInstance()
{
????????
return
?hungrySingleton;
????}
????

????
/**?*/
/**
?????*?示例業務方法
?????
*/
????
public
?
void
?demoMethod()
{
????????
//
do?something
????}
}
/**/
/*
?*?懶漢是單例類?Lazy?Singleton
?@author?ZhangPu
?Feb?22,?2007?7:41:26?PM
?
*/
public
?
class
?LazySingleton?
{


????
/**?*/
/**
?聲明單例自身實例變量?
*/
????
private
?
static
?LazySingleton?lazySingleton?
=
?
null
;

????
/**?*/
/**
?????*?私有構造
?????
*/
????
private
?LazySingleton()
{}
????

????
/**?*/
/**
?????*?單例方法
?????*?
@return
?????
*/
????
public
?
static
?LazySingleton?getInstance()
{

????????
if
(lazySingleton?
==
?
null
)
{
????????????lazySingleton?
=
?
new
?LazySingleton();
????????}
????????
return
?lazySingleton;
????}
????

????
/**?*/
/**
?????*?示例業務方法
?????
*/
????
public
?
void
?demoMethod()
{
????????
//
do?something
????}
}
2、登記式單例類
主要是解決餓漢和懶漢式單例類不能使用繼承的情況設計的。由父類提供一個集合裝載子類的實例,并通過傳入參數來提供子類的唯一實例。父類實現實例創造和管理,子類傳入參數取得實例。
package?pattern.singleton;

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


/**//*
?@author?ZhangPu
?Feb?22,?2007?7:50:28?PM
?*/


public?abstract?class?RegSingleton?
{

????private?static?Map?registers?=?new?HashMap();
????

????/**?*//**
?????*?保護默認構造
?????*
?????*/

????protected?RegSingleton()
{}
????

????public?static?RegSingleton?getInstance(String?key)
{

????????if(key?==?null)
{
????????????key?=?"pattern.singleton.RegSingleton";
????????}

????????if(registers.get(key)?==?null)
{

????????????try?
{
????????????????registers.put(key,?Class.forName(key).newInstance());

????????????}?catch?(Exception?e)?
{
????????????????e.printStackTrace();
????????????}
????????}
????????return?(RegSingleton)registers.get(key);
????}
????

????/**?*//**
?????*?示例業務方法,子類實現
?????*
?????*/

????public?void?busiMethod1()
{System.out.println("busiMethod1");}

????public?void?busiMethod2()
{}

????public?void?busiMethod3()
{}
}

package?pattern.singleton;


/**//*
?@author?ZhangPu
?Feb?22,?2007?8:01:27?PM
?*/


public?class?RegSingletonChild?extends?RegSingleton?
{


????public?RegSingletonChild()?
{
????????//?TODO?Auto-generated?constructor?stub
????}
????

????/**//*
?????*?@Override
?????*/

????public?static?RegSingletonChild?getInstance()
{
????????return?(RegSingletonChild)RegSingleton.getInstance("pattern.singleton.RegSingletonChild");
????}


????public?static?void?main(String[]?args)?
{
????????RegSingletonChild?reg?=??RegSingletonChild.getInstance();
????????reg.busiMethod1();
????}
????
} 一個實際的例子
本例用戶在一個真實的行業管理系統中提供代碼表的鍵值緩存。
package?net.zphome.tools;

import?java.util.HashMap;
import?java.util.Iterator;
import?java.util.Map;
import?java.util.TreeMap;

import?net.zphome.db.DbResultSet;
import?net.zphome.db.Dbsql;



/**//*
?@author?ZhangPu
?Jul?31,?2006?9:18:25?PM
?*/


public?class?CacheDD?
{

????
????public?static?Map?dd?=?null;
????

????static
{

????????if(dd?==?null)
{
????????????loadDataDictionary();?
????????}????
????}
????

????public?static?Map?getDDByType(String?typeid)
{

????????return?(Map)dd.get(typeid);
????}
????
????

????public?static?String?getDDWithOption(String?TypeId)
{
????????StringBuffer?sb?=?new?StringBuffer();
????????
????????Map?one?=?(Map)dd.get(TypeId);
????????Iterator?it?=?one.keySet().iterator();

????????while(it.hasNext())
{
????????????String?key?=?(String)it.next();
????????????sb.append("<option?value=\""+key+"\">"+one.get(key)+"</option>\n");
????????}
????????return?sb.toString();
????}
????

????public?static?String?getDDWithOption(String?TypeId,String?defaultKey)
{
????????StringBuffer?sb?=?new?StringBuffer();
????????
????????Map?one?=?(Map)dd.get(TypeId);
????????Iterator?it?=?one.keySet().iterator();

????????while(it.hasNext())
{
????????????String?key?=?(String)it.next();
????????????sb.append("<option?value=\""+key+"\"?"+(defaultKey?!=?null?&&?defaultKey.equals(key)?"selected":"")+">"+one.get(key)+"</option>\n");
????????}
????????return?sb.toString();
????}
????

????public?static?String?getDDValueByKey(String?TypeId,String?key)
{
????????Map?one?=?(Map)dd.get(TypeId);
????????return?(String)one.get(key);
????}
????
????

????private?static?void?loadDataDictionary()
{
????????dd?=?new?HashMap();
????????
????????Dbsql?sql?=?null;
????????DbResultSet?rs?=?null;

????????try?
{
????????????sql?=?new?Dbsql();
????????????String?strSql?=?"select?TYPE_ID,DD_ID,DD_NAME?FROM?SYS_DD?ORDER?BY?TYPE_ID?";
????????????rs?=?sql.executeQuery(strSql);

????????????if(rs?!=?null)
{
????????????????Map?oneType?=?null;
????????????????int?i?=?0;
????????????????String?prevType?=?"";

????????????????while(rs.next())
{

????????????????????if(!prevType.equals(rs.getString(1)))
{

????????????????????????if(oneType?!=?null)
{
????????????????????????????dd.put(prevType,oneType);
????????????????????????}
????????????????????????oneType?=?new?TreeMap();?
????????????????????}???????????????
????????????????????oneType.put(rs.getString(2),rs.getString(3));??????????????
????????????????????prevType?=?rs.getString(1);

????????????????}

????????????????if(oneType?!=?null)
{
????????????????????dd.put(prevType,oneType);
????????????????}
????????????????rs.close();
????????????}
????????????

????????}?catch?(Exception?e)?
{
????????????throw?new?RuntimeException(e);

????????}finally
{
????????????sql?=?null;
????????}
????}
????

????public?static?void?main(String[]?args)?
{

????????/**//*
????????Map?one?=?CacheDataDictionary.getDDByType("1");
????????Iterator?it?=?one.keySet().iterator();
????????while(it.hasNext()){
????????????System.out.println(it.next());
????????}
????????*/
????????System.out.println(CacheDD.getDDWithOption("1"));
????????System.out.println(CacheDD.getDDWithOption("2","1"));
????}

}

參考:《JAVA與模式》 閻宏 電子工業出版社