常用設計模式-單例模式
是什么
單例模式是一種常見的軟件設計模式,他的核心結構中只包含一個被稱為單例的特殊類,通過單例可以保證系統中,應用該模式的一個類只有一個實例,即一個類只有一個實例對象。
有什么
單例模式要求類能過有返回對象的一個引用和獲取該實例的一個方法(必須是一個靜態方法,一般使用getInstance這個名詞命名)
怎么做
單例的實現主要是通過以下步驟:
- 定義一個私有的靜態引用(即屬性)
- 將類的構造方法定義為私有方法,這樣其他的代碼無法通過調用該類的方法來實例對象,只有通過該類提供的靜態方法來得到實例
- 在該類提供一個靜態方法,當我們調用這個方法的時候如果類持有的引用不為空就返回這個引用,如果為空就創建這個對象的實例并將實例只想改類的引用
代碼實例
- 餓漢模式(靜態常量)
public class Singleton{
private static Singleton singleton=new Singleton();
private Singleton(){}
private static Singleton getInstance(){
return singleton;
}
}
- 餓漢模式(靜態代碼庫)
public class Singleton{
private static Singleton singleton;
static {
singleton =new Singleton();
}
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
}
- 懶漢模式不同步
public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton ==null ){
singleton=new Singleton();
}
return singleton;
}
}
- 懶漢模式同步
public class Singleton{
private static Singleton singleton;
private Singleton(){}
public synchronized static Singleton getInstance(){
if(singleton == null){
singleton=new Singleton();
}
return singleton;
}
}
- 懶漢模式(同步)
public class Singleton{
private static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
singleton=new Singleton();
}
}
return singleton;
}
}
- 枚舉類型
public enum Singleton{
Instance;
public void hello(){
}
}
- 靜態內部類
public class Singleton{
private Singleton(){}
private static class SingletonInstance{
private static final Singleton INSTANCE=new Singeton();
}
private static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
- 雙重檢查
public class Singleton{
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
什么時候用
- 需要頻繁的創建和銷毀對象
- 創建對象耗時過多或者耗費資源過多,但又經常用到
- 工具類對象
- 頻繁訪問數據庫或者文件的對象
優缺點
- 優點:系統中該類只存在一個對象,節省了資源,對于頻繁創建或者使用的對象使用單例可以提高系統性能
- 缺點:實例化必須通過靜態方法獲取而不是new;