1、單例模式定義
確保某一個類只有一個實例,並且自行實例化並向整個系統提供這個實例。
git
2、單例模式的應用
1.單例模式的優勢
- 因爲單例模式再內存中只有一個實例,減小了內存開支,特別是一個對象須要頻繁地建立、銷燬時,並且建立或銷燬時性能又沒法優化,單例模式的優點就很是明顯;
- 因爲單例模式只生成一個實例,因此減小了系統的性能開銷,當一個對象的產生須要比較多的資源時,如讀取配置、產生其餘依賴對象時,則能夠經過在應用啓動時直接產生一個單例對象,而後用永久駐留內存的方式解決(在JavaEE中採用單例模式時須要注意JVM垃圾回收機制);
- 單例模式能夠避免對資源的多重佔用,例如一個寫文件動做,因爲只有一個實例存在內存中,避免對同一個資源文件的同時寫操做;
- 單例模式能夠在系統設置全局的訪問點,優化和共享資源訪問,例如能夠設計一個單例類,負責全部數據表的映射處理;
2.單例模式的缺點
- 單例模式通常沒有接口,擴展很困難,若要擴展,除了修改代碼基本上沒有第二種途徑能夠實現。單例模式爲何不能增長接口呢?由於接口對單例模式是沒有意義的,它要求」自行實例化」,而且提供單一實例、接口或抽象類是不可能被實例化的。固然,在特殊狀況下,單例模式能夠實現接口、被繼承等,須要在系統開發中根據環境判斷;
- 單例模式對測試是不利的。在並行開發環境中,若是單例模式沒有完成,是不能進行測試的,沒有接口也不能使用mock的方式虛擬一個對象;
- 單例模式與單一職責原則有衝突。一個類應該只實現一個邏輯,而不關心它是不是單例的,是否是要單例取決於環境,單例模式把」要單例」和業務邏輯融合在一個類中;
3.單例模式的使用場景
- 要求生成惟一序列號的環境;
- 在整個項目中須要把一個共享訪問點或共享數據,例如一個Web頁面上的計數器,能夠不用把每次刷新都記錄到數據庫中,使用單例模式保持計數器的值,並確保是線程安全的;
- 建立一個對象須要消耗的資源過多,如要訪問IO和數據庫等資源;
- 須要定義大量的靜態常量和靜態方法(如工具類)的環境,能夠採用單例模式(固然,也能夠直接聲明爲static的方式);
3、最佳實踐
單例模式是23個模式中比較簡單的模式,應該也很是普遍,如在Spring中,每一個Bean默認就是單例的,這樣作的優勢是Spring容器能夠管理這些Bean的生命期,決定何時建立出來,何時銷燬,銷燬的時候要如何處理,等等。若是採用非單例模式,則Bean初始化後的管理交由J2EE容器,Spring容器再也不跟蹤管理Bean的生命週期。github
代碼例子:https://github.com/developers-youcong/DesignPatternPractice/tree/master/Singleton數據庫