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