设计模式 之 单例模式

      首先来介绍一下单例模式它用来创建独一无二的,只能有一个实例的对象,像线程池、缓存、注册表等。单件模式给了我们一个全局的访问点,和全局变量一样方便,而且有过之而无不及——如果将对象赋值给一个全部变量,我们必须在程序的一开始就创建好这个变量,而使用单例模式,我们可以在需要时才创建对象。

      在没有学习单例模式之前,我们创建对象都是用 new MyObject(); 来创建的,这时,如果另一个对象想创建MyObject,也是可以再次创建,可见,使用以前的方法,我们不能保证所有使用者都共用一个实例——因为所有使用者都可以随时随地NEW一个实例出来。当然,这里面也涉及到一个访问修饰符的问题,如果类是用public关键字修饰的,则使用者可以在任何地方实例化变量;如果不是public修饰的类,则只有同一个包内的类才可以创建这个类的实例,但仍是可以多次实例化这个类。所以,如果我们想让这个类能够只实例化一次,我们需要用到以下的代码:

1 public class MyObject{
2     private MyObject() {
3         // TODO 要做的动作
4     }
5 }
第一步的代码

      我们会发现,我们再也不能使用 new MyObject(); 来创建对象了,确切的说,我们再也不能创建MyObject的实例了。因此,我们需要使用一种机制来可以让我们在现在的代码基础上创建出MyObject对象,并且还要符合我们最初的需求:全局只能创建一个MyObject对象。由此,我们写出了以下的代码:

 1 public class MyObject {
 2     // 将构造方法私有化,不允许外部直接创建对象
 3     private MyObject() {
 4     }
 5 
 6     // 创建类的唯一实例
 7     private static MyObject instance = new MyObject();
 8 
 9     // 提供一个用于获取实例的方法
10     public static MyObject getInstance() {
11         return instance;
12     }
13 }
第二步的代码

      这样一来,我们只需在要使用MyObject对象时调用 MyObject m = MyObject.getInstance(); 来获取MyObject实例。我们称这种方法为“饿汉模式”。

      还有一种“懒汉模式”,代码如下:

 1 public class MyObject {
 2     // 将构造方法私有化,不允许外部直接创建对象
 3     private MyObject() {
 4     }
 5 
 6     // 创建类的唯一实例
 7     private static MyObject instance;
 8 
 9     // 提供一个用于获取实例的方法
10     public static MyObject getInstance() {
11         if (instance == null) {
12             instance = new MyObject();
13         }
14         return instance;
15     }
16 }
懒汉模式代码

 

“饿汉模式”和“懒汉模式”的比较如下:
  饿汉模式:在类加载的时候就创建类的实例,因此加载类时比较慢,但运行时获取对象的速度比较快,线程安全
  懒汉模式:在类加载的时候并没有创建类的实例,因此加载类比饿汉模式快,但运行时获取对象的速度比较快,线程不安全

 

你可能感兴趣的:(设计模式 之 单例模式)