设计模式(一):单例模式

175 阅读2分钟

介绍

单例模式(Singleton Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。保证一个类仅有一个实例,并提供一个访问它的全局访问点,可以直接访问,不需要实例化该类的对象。

优点

  • 在内存里只有一个实例,减少了内存、性能的开销,尤其是频繁的创建和销毁实例
  • 避免对资源的多重占用(比如写文件操作)

缺点

  • 没有接口,不能继承,拓展困难
  • 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

应用

随处可见,比如一些框架的初始化啊,repository等等

实现

创建该类:

class SingleObject {

   private SingleObject(){}
   // 让构造函数为 private,这样该类就不会被实例化,单例模式的精髓
 
   private static SingleObject instance = new SingleObject();
 
   public static SingleObject getInstance(){
      return instance;
   }

}

其他实现方式:

1. 懒汉式(线程不安全)

// 最基本的实现方式,不支持多线程
public class Singleton {  

   private Singleton (){}  
   
   private static Singleton instance;  
 
   public static Singleton getInstance() {  
       if (instance == null) {  
           instance = new Singleton();  
       }  
       return instance;  
   }  
}

2. 懒汉式(线程安全)

// 线程安全,但是性能较低
public class Singleton {  

   private Singleton (){}
   
   private static Singleton instance;  
     
   public static synchronized Singleton getInstance() {  
       if (instance == null) {  
           instance = new Singleton();  
       }  
       return instance;  
   }  
}

3. 饿汉式

// 线程安全,在类装载时就实例化,但容易产生垃圾对象
public class Singleton {  

   private Singleton (){}  
 
   private static Singleton instance = new Singleton();  
   
   public static Singleton getInstance() {  
       return instance;  
   }  
}

4.双检锁/双重校验锁

//  ### 即 double-checked locking,线程安全且在多线程情况下能保持高性能,实现复杂
public class Singleton {  

   private volatile static Singleton singleton;  
   
   private Singleton (){}  
   
   public static Singleton getSingleton() {  
       if (singleton == null) {  
           synchronized (Singleton.class) {  
               if (singleton == null) {  
                   singleton = new Singleton();  
               }  
           }  
       }  
       return singleton;  
     }  
  }

5.静态内部类

//饿汉式只要类装载的时候就创建对象,但是静态内部类的方法在getInstance才初始化,并且线程安全

public class Singleton {  

   private static class SingletonHolder {  
       private static final Singleton INSTANCE = new Singleton();  
   }  
   
   private Singleton (){}  
   
   public static final Singleton getInstance() {  
       return SingletonHolder.INSTANCE;  
   }  
}

6.枚举

//实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。
public enum Singleton {  
   INSTANCE;  
   public void whateverMethod() {  
   }  
}