设计方式学习与使用杂谈之单例模式
设计模式学习与使用杂谈之单例模式
单例模式
问题:如果想要系统中某个类的实例只有一个,该怎么解决?
解决过程:
首先要知道类的实例化是通过构造函数来完成的,也就是我们常说的new操作符,在java中,如果没有显示的定义构造函数,将会使用默认的构造函数,而默认的构造函数是public的(即系统全局所有),因此解决上一个问题的第一步就是把构造函数修改为private(私有)的,这样,类之外就不能在使用构造函数进行实例化该类。
但是如果外部类要访问该类,该类就要提供有一个全局静态的方法。如下代码:
原代码:
public class SingletonDemo{ public SingletonDemo(){ } }
修改后代码1:
public class SingletonDemo{
private SingletonDemo(){
}
public SingletonDemo getInstance(){
//.....
}
}
我们要使用方法getInstance()返回类的唯一实例:
修改后代码2:
public class SingletonDemo{ private SingletonDemo(){ } private static final SingletonDemo INSTANCE = new SingletonDemo(); public SingletonDemo getInstance(){ return INSTANCE; } }
类定义了一个静态的常量INSTANCE,该实例不能进行修改,保证了该类只有一个实例。外部类想要使用该类的实例,只需要:SingletonDemo.getInstance();
如果我们不想使用静态常量INSTACE,想把实例化在getInstance()中进行,如下:
修改后代码3:
public class SingletonDemo{ private SingletonDemo(){ } private static SingletonDemo singletonInstance = null; public SingletonDemo getInstance(){ if(singletonInstance == null) singletonInstance = new SingletonDemo(); return singletonInstance ; } }
但是当并发的时候,将会产生多个实例,因此要做同步控制:
修改后代码4:
public class SingletonDemo{ private SingletonDemo(){ } private synchronized static SingletonDemo singletonInstance = null; public SingletonDemo getInstance(){ if(singletonInstance == null) singletonInstance = new SingletonDemo(); return singletonInstance ; } }
修改后代码2和修改后代码4就是单例模式的两种表现形式,使某一个类在系统中只有一个实例。
另外在jdk1.5中提供了枚举类,因此在jdk1.5及以后的版本,实现单例模式有了第三种方式,而且以后也将成为最流行最简单的方式:单元素的枚举类表示单例类