單列模式

單例模式是一種常見的設計模式,在網上有許多,一找一大把,我今天看了,所以collection一下:
單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。
單例模式有一下特點:
1、單例類只能有一個實例。
2、單例類必須自己自己創建自己的唯一實例。
3、單例類必須給所有其他對象提供這一實例。
一、懶漢式單例
在類被加載的時候,唯一實例已經被創建。這個設計模式在Java中容易實現,在別的語言中難以實現。
/**
*懶漢式單例
*/
public class LazySingleton {
     /**
      * 私有靜態對象,加載時候不做初始化
      */
     private static LazySingleton m_intance=null;
     /**
      * 私有構造方法,避免外部創建實例
      */
     private LazySingleton(){
     }
     /**
      * 靜態工廠方法,返回此類的唯一實例. 
      * 當發現實例沒有初始化的時候,才初始化.
      * @return LazySingleton
      */
     synchronized public static LazySingleton getInstance(){
         if(m_intance==null){
             m_intance=new LazySingleton();
         }
         return m_intance;
     }
}
二、餓漢式單例
在類加載的時候不創建單例實例。只有在第一次請求實例的時候的時候創建,並且只在第一次創建後,以後不再創建該類的實例。
/**
*單例模式-餓漢式單例
*/
public class EagerSingleton {
     /**
      * 私有的(private)唯一(static final)實例成員,在類加載的時候就創建好了單例對象
      */
     private static final EagerSingleton m_instance = new EagerSingleton();
     /**
      * 私有構造方法,避免外部創建實例
      */
     private EagerSingleton() {
     }
     /**
      * 靜態工廠方法,返回此類的唯一實例.
      * @return EagerSingleton
      */
     public static EagerSingleton getInstance() {
         return m_instance;
     }
}
三、登記式單例
這個單例實際上維護的是一組單例類的實例,將這些實例存放在一個Map(登記薄)中,對於已經登記過的實例,則從工廠直接返回,對於沒有登記的,則先登記,而後返回。
/**
* 單例模式- 登記式單例
*/
public class RegSingleton {
     /**
      * 登記薄,用來存放所有登記的實例
      */
     private static Map<String, RegSingleton> m_registry = new HashMap();
     //在類加載的時候添加一個實例到登記薄
     static {
         RegSingleton x = new RegSingleton();
         m_registry.put(x.getClass().getName(), x);
     }
     /**
      * 受保護的默認構造方法
      */
     protected RegSingleton() {
     }
     /**
      * 靜態工廠方法,返回指定登記對象的唯一實例;
      * 對於已登記的直接取出返回,對於還未登記的,先登記,然後取出返回
      * @param name
      * @return RegSingleton
      */
     public static RegSingleton getInstance(String name) {
         if (name == null) {
             name = "RegSingleton";
         }
         if (m_registry.get(name) == null) {
             try {
                 m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());
             } catch (InstantiationException e) {
                 e.printStackTrace();
             } catch (IllegalAccessException e) {
                 e.printStackTrace();
             } catch (ClassNotFoundException e) {
                 e.printStackTrace();
             }
         }
         return m_registry.get(name);
     }
     /**
      * 一個示意性的商業方法
      * @return String
      */
     public String about() {
         return "Hello,I am RegSingleton!";
     }
}
四、單例模式的一個應用
該應用是配置文件管理類。爲了本例能正確運行,我在C盤下先建立了一個xxxx.properties文件,內容如下:
-------------------
user=root
password=root

這個配置文件管理類的代碼如下:
/**
*
* 單例模式應用-單例類應用-配置文件管理
*/
public class ConfigManager {
     /**
      * 屬性文件全名
      */
     private static final String PFILE = "C://xxx.properties";
     /**
      * 對應於屬性文件的文件對象變量
      */
     private File m_file = null;
     /**
      * 屬性文件的最後修改日期
      */
     private long m_lastModifiedTime = 0;
     /**
      * 屬性文件所對應的屬性對象變量
      */
     private Properties m_props = null;
     /**
      * 本類可能存在的唯一的一個實例
      */
     private static ConfigManager m_instance = new ConfigManager();
     /**
      * 私有構造子,用以保證外界無法直接實例化
      */
     private ConfigManager() {
         m_file = new File(PFILE);
         m_lastModifiedTime = m_file.lastModified();
         if (m_lastModifiedTime == 0) {
             System.err.println(PFILE + " file does not exist!");
         }
         m_props = new Properties();
         try {
             m_props.load(new FileInputStream(PFILE));
         } catch (IOException e) {
             e.printStackTrace();
         }
     }
     /**
      * 靜態工廠方法
      *
      * @return ConfigManager
      */
     synchronized public static ConfigManager getInstance() {
         return m_instance;
     }
     /**
      * 獲取屬性配置項的值
      *
      * @param name
      * @param defaultVal
      * @return Object
      */
     public final Object getConfigItem(String name, Object defaultVal) {
         long newTime = m_file.lastModified();
         if (newTime == 0) {
             //屬性文件不存在
             if (m_lastModifiedTime == 0) {
                 System.err.println(PFILE + " file does not exist!");
             } else {
                 System.err.println(PFILE + " file was deleted!");
             }
             return defaultVal;
         } else if (newTime > m_lastModifiedTime) {
             m_props.clear();
             try {
                 m_props.load(new FileInputStream(PFILE));
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
         m_lastModifiedTime = newTime;
         Object val = m_props.getProperty(name);
         if (val == null) {
             return defaultVal;
         } else {
             return val;
         }
     }
}
測試配置文件類:
/**
*
* 配置文件管理類測試
*/
public class Test_ConfigManager {
     public static void main(String[] args) {
         ConfigManager cfgm = ConfigManager.getInstance();
         Object val1 = cfgm.getConfigItem("sdf", "leizhimin");
         Object val2 = cfgm.getConfigItem("user", "leizhimin");
         System.out.println(val1.toString());
         System.out.println(val2.toString());
     }
}
運行結果:
root

root
Process finished with exit code 0

發佈了83 篇原創文章 · 獲贊 26 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章