A Cooly Weblog

   ::  ::  ::  ::  :: 管理

单例模式Singleton

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

只有注册用户登录后才能发表评论。


网站导航: