设计方式学习与使用杂谈之单例模式

设计模式学习与使用杂谈之单例模式

单例模式

 

问题:如果想要系统中某个类的实例只有一个,该怎么解决?

 

解决过程:

                    首先要知道类的实例化是通过构造函数来完成的,也就是我们常说的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及以后的版本,实现单例模式有了第三种方式,而且以后也将成为最流行最简单的方式:单元素的枚举类表示单例类