1. 程式人生 > >設計模式 _第一招式_單例模式

設計模式 _第一招式_單例模式

一、定義
單例模式(Singleton Pattern)是一個比較簡單的模式,確保某一個類只有一個例項,而且自行例項化並向整個系統提供這個例項。

二、程式碼演示
Singleton 類稱為單例類,通過使用private的建構函式確保在一個應用中只產生一個例項,並且自行例項化,單例(飽漢式)通用原始碼如下:

public class Singleton {
    private  static Singleton singleton = new  Singleton ();
    //限制通過建構函式,產生多個例項
    private Singleton(){}

    //通過該方法獲得例項物件
public static Singleton getSingleton(){ return singleton ; } //其它方法儘量是static public static void doSomething(){ } }

三、優點

  1. 由於單例在應用中只有一個例項,減少了記憶體開支,特別是一個物件頻繁的建立銷燬時,而且建立銷燬例項無法優化,單例的優勢非常明顯。
  2. 由於單例只生成一個例項,所以減少了效能開銷,當一個物件的產生需要較多資源時如讀取配置、產生其它依賴物件時,則可以在啟動應用時候,直接產生一個單例物件,然後永久駐留記憶體中(在java ee 使用單例時,需要注意JVM垃圾回收機制)。
  3. 單例可以避免資源多重佔用,例如寫一個檔案動作,由於只有一個例項存在,避免同一個資原始檔被重複處理。
  4. 單例模式可以在系統設定全域性的訪問點,優化和共享資源訪問, 如可以設計一個單例類負責所有資料表的對映處理。

四、缺點

  1. 單例模式一般沒有介面,擴充套件困難,若要擴充套件,除了修改程式碼基本上沒有第二種途徑。單例模式為什麼沒有介面?單例模式要求“自行例項化”,介面或抽象類不能例項化。
  2. 單例模式對測試是不利的,在並行開發環境,如果沒有完成單例類,是不能進行測試的,沒有介面不能使用mock的方式虛擬一個物件。

五、應用場景

  1. 要求生產唯一序號環境;
  2. 在專案中需要一個共享訪問點或共享資料,如一個web專案中的計數器,可以不將資料儲存到資料庫,使用單例模式儲存計數器的值,並確保是執行緒安全的;
  3. 建立一個物件需要消耗的資源過多, 如訪問IO和資料庫等資源;
  4. 需要定義大量的靜態常量和靜態方法(工具)的環境;

六、注意事項

  1. 在高併發時,請注意單例模式的執行緒同步問題,如下是執行緒不安全的單例(懶漢式):
 public class Singleton {
    private  static Singleton singleton = null;
    //限制通過建構函式,產生多個例項
    private Singleton(){}
    //通過該方法獲得例項物件
    public static Singleton getSingleton(){
        if (singleton == null){
            return  new Singleton() ;
        }
        return singleton ;
    }
    //其它方法儘量是static
    public static void doSomething(){
    }
}

解決執行緒不安全的方法很多, 一般加synchronized關鍵字來實現。
2. 需要考慮物件複製的情況,在java中,物件預設是不可以被複制的,如要Cloneable介面,並實現了clone方法,則可以直接通過物件複製的方式建立一個新物件,物件複製不是呼叫類的建構函式,因此即使是私有的建構函式,物件仍然可以被複制。一般情況下,類複製的情況不用考慮,很少有類出現一個單例類會主動要求被複制,解決此問題最好的方法是,單例類不要事先Cloneable介面。