单例模式
单例(Singleton)模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类 。
1、单例模式的要点:
- 某个类只能有一个实例;
- 它必须自行创建这个实例;
- 它必须自行向整个系统提供这个实例。
2、单例模式的例子:
- 打印机;
- 传真机使用的传真卡,只应该由一个软件管理;
- Windows回收站。
3、单例模式有以下特点:
- 单例类只能有一个实例;
- 单例类必须自己创建自己的唯一的实例;
- 单例类必须给所有其他对象提供这一实例;
- 私有构造方法,避免外部创建实例;
- 私有静态实例;
- 静态工厂方法,返回此单例类唯一的实例。
4、使用单例模式的条件:
- 使用单例模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式,反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例模式类。
饿汉式单例类:
public class EagerSingleton { private static final EagerSingleton m_instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return m_instance; } }
* java语言中单例类的一个最重要的特点是类的构造方法是私有的,从而避免外界利用构造子直接创建出任意多的实例。因为构造子是私有的,因此此类不能被继承。饿汉式单例类在类加载的时候就实例化一个自己的对象。
懒汉式单例类:
public class LazySingleton { private static LazySingleton m_instance = null; private LazySingleton() { } synchronized public static LazySingleton getInstance() { if (m_instance == null) { m_instance = new LazySingleton(); } return m_instance; } }
* 与饿汉式单例类相同的是,懒汉式单例类的构造方法是私有的,不同的是在第一次被引用时才将自己实例化,如果加载器是静态的,那么在懒汉式单例类被加载时不会将自己实例化。
登记式单例类:
public class RegSingleton { private static HashMap m_registry = new HashMap(); static { RegSingleton x = new RegSingleton(); m_registry.put(x.getClass().getName(), x); } protected RegSingleton() { } public static RegSingleton getInstance(String name) { if (name == null) { name = "RegSingleton"; } if (m_registry.get(name) == null) { try { m_registry.put(name, Class.forName(name).newInstance()); } catch (Exception e) { System.out.println("Error happened."); } } return (RegSingleton) (m_registry.get(name)); } // 一个示意性的商业方法 public String about() { return "Hello, I am RegSingleton"; } } // 登记式单例类的子类 public class RegSingletonChild extends RegSingleton { public RegSingletonChild() { } // 静态工厂方法 public static RegSingletonChild getInstance(){ return (RegSingletonChild)RegSingleton.getInstance("RegSingleton") } public String about() { return "Hello, I am RegSingletonChild"; } }
* 登记式单例这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。
**