单例模式

来源:互联网 发布:python ascii转字符 编辑:程序博客网 时间:2024/06/05 15:47
单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例 

单例的3个要素: 
1)一个类只能有一个实例 
2)必须自行创建 
3)必须自行向这个系统提供这个实例 
注意:构造子是私有的,不能被继承(登记式单例除外) 

3种单例: 
1)饿汉式单例 
2)懒汉式单例 
3)登记式单例 

单例状态 
有状态:通常的形式是:有属性,无方法,例如:计数器,状态库(reopsitory) 
无状态:通常的形式是:有方法,无属性,例如:工具性函数对象 

例子: 
资源管理器 
打印机 
通信端口管理 
系统属性文件(properties) 
回收站 

1)懒汉、饿汉式单例 
Eager_Lazy.java 
Java代码  收藏代码
  1. /** 
  2.  * static 修饰的变量和代码区,只有在该类的静态方法或属性在第一次被访问的时候,才会初始化 
  3.  * static final 修饰的变量,是在编译期间就会被初始化 
  4.  * static final修饰的的对象或者变量,在加载类之前就存在 
  5.  */  
  6.   
  7. // 饿汉式单例类.在类初始化时,已经自行实例化  
  8. class EagerSingleTon {  
  9.     private static final EagerSingleTon instance = new EagerSingleTon();  
  10.   
  11.     private EagerSingleTon() {  
  12.     }  
  13.   
  14.     public static EagerSingleTon getInstance() {  
  15.         return instance;  
  16.     }  
  17. }  
  18.   
  19. // 懒汉式单例类,在第一次调用的时候被实例化  
  20. class LazySingleTon {  
  21.     // 注意,这里没有final  
  22.     private static LazySingleTon instance = null;  
  23.   
  24.     private LazySingleTon() {  
  25.     }  
  26.   
  27.     public synchronized static LazySingleTon getInstance() {  
  28.         if (instance == null) {  
  29.             instance = new LazySingleTon();  
  30.         }  
  31.         return instance;  
  32.     }  
  33. }  

2)登记式单例 
RegSingleton.java 
Java代码  收藏代码
  1. package CreationalPattern.Singleton;  
  2.   
  3. import java.util.HashMap;  
  4. /* 
  5. 目的:克服懒汉式和饿汉式单例不能集成的缺点而设计. 
  6.  缺点1:父类构造子公开,可以不登记 
  7.  缺点2:父类必须存在,才能有子类 
  8.  */  
  9. public class RegSingleton {  
  10.     static private HashMap m_registry = new HashMap();  
  11.     static {  
  12.         RegSingleton x = new RegSingleton();  
  13.         m_registry.put(x.getClass().getName(), x);  
  14.     }  
  15.   
  16.     protected RegSingleton() {  
  17.     }  
  18.   
  19.     static public RegSingleton getInstance(String name) {  
  20.         if (name == null) {  
  21.             name = "CreationalPattern.Singleton.RegSingleton";  
  22.         }  
  23.         if (m_registry.get(name) == null) {  
  24.             try {  
  25.                 m_registry.put(name, Class.forName(name).newInstance());  
  26.             } catch (Exception e) {  
  27.             }  
  28.         }  
  29.         return (RegSingleton) (m_registry.get(name));  
  30.     }  
  31.       
  32.     /** 
  33.      * 示例方法 
  34.      */  
  35.     public String about(){  
  36.         return "this is RegSingleton.";  
  37.     }  
  38. }  

RegSingletonChild.java 
Java代码  收藏代码
  1. package CreationalPattern.Singleton;  
  2.   
  3. public class RegSingletonChild extends RegSingleton {  
  4.     //必须公开  
  5.     public RegSingletonChild() {  
  6.     }  
  7.       
  8.     static public RegSingletonChild getInstance(){  
  9.         //在父类里new的子类,所以子类的构造子必须是公开的  
  10.         return (RegSingletonChild)(RegSingleton.getInstance("CreationalPattern.Singleton.RegSingletonChild"));  
  11.     }  
  12.       
  13.     public String about(){  
  14.         return "this is RegSingletonChild.";  
  15.     }  
  16. }  

TestSingleton.java 
Java代码  收藏代码
  1. package CreationalPattern.Singleton;  
  2. public class TestSingleton {  
  3.   
  4.     public static void main(String[] args) {  
  5.         TestSingleton t = new TestSingleton();  
  6.         System.out.println(t.getClass().getName());  
  7.         System.err.println("error!");  
  8.           
  9.         //4种调用登记式单例的方式  
  10.         System.out.println(RegSingleton.getInstance("CreationalPattern.Singleton.RegSingleton").about());  
  11.         System.out.println(RegSingleton.getInstance(null).about());  
  12.         System.out.println(RegSingletonChild.getInstance().about());  
  13.         System.out.println(RegSingletonChild.getInstance("CreationalPattern.Singleton.RegSingletonChild").about());  
  14.     }  
  15. }  
0 0
原创粉丝点击