单例模式又叫做单态模式或者单件模式。在GOF书中给出的定义为:保证一个类仅有一个实例,并提供一个访问它的全局访问点。单例模式中的“单例”通常用来代表那些本质上具有唯一性的系统组件(或者叫做资源)。比如文件系统、资源管理器等等。
单例模式的目的就是要控制特定的类只产生一个对象,当然也允许在一定情况下灵活的改变对象的个数。那么怎么来实现单例模式呢?一个类的对象的产生是由类构造函数来完成的,如果想限制对象的产生,就要将构造函数变为私有的(至少是受保护的),使得外面的类不能通过引用来产生对象;同时为了保证类的可用性,就必须提供一个自己的对象以及访问这个对象的静态方法。
public class Singleton {
//在自己内部定义自己一个实例
//注意这是private 只供内部调用
private static Singleton instance = new Singleton();
//如上面所述,将构造函数设置为私有
private Singleton(){
}
//静态工厂方法,提供了一个供外部访问得到对象的静态方法
public static Singleton getInstance() {
return instance;
}
}
下面这种方式被称为懒汉式:
public class Singleton {
//和上面有什么不同?
private static Singleton instance = null;
//设置为私有的构造函数
private Singleton(){
}
//静态工厂方法
public static synchronized Singleton getInstance() {
//这个方法比上面有所改进
if (instance==null)
instance=new Singleton();
return instance;
}
}
先让我们来比较一下这两种实现方式。
首先他们的构造函数都是私有的,彻底断开了使用构造函数来得到类的实例的通道,但是这样也使得类失去了多态性(大概这就是为什么有人将这种模式称作单态模式)。
在第二种方式中,对静态工厂方法进行了同步处理,原因很明显——为了防止多线程环境中产生多个实例;而在第一种方式中则不存在这种情况。
在第二种方式中将类对自己的实例化延迟到第一次被引用的时候。而在第一种方式中则是在类被加载的时候实例化,这样多次加载会照成多次实例化。但是第二种方式由于使用了同步处理,在反应速度上要比第一种慢一些。