Posted on 2007-02-22 18:48
acooly 阅读(421)
评论(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与模式》 阎宏 电子工业出版社