23種設計模式介紹以及單例模式的學習
1、GOF23 設計模式總共分成創建型模式、結構型模式和行為型模式三種:
a、創建型模式:
- 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式
b、構建型模式:
- 適配器模式、橋接模式、裝配模式、組合模式、建造者模式、原型模式
c、行為性模式:
- 模版方法模式、命令模式、叠代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式、狀態模式、策略模式、職責鏈模式、訪問者模式。
2、下面介紹單例模式:(在後面的博文中會一一介紹主要的設計模式)
a、核心作用:保證一個類只有一個實例,並且提供一個訪問該實例的全局訪問點。
b、單例模式的優點:
-由於單例模式只生成一個實例,減少了系統性能開銷,當一個對象的產生需要比較多的資源時,如讀取配置、產生其他依賴的對象時,則可以通過在應用啟動時直接產生一個單例對象,然後永久駐留內存的方式來解決。
-單例模式可以在系統設置全局的訪問點,優化共享資源訪問,例如可以設計一個單例類,負責所有的數據表的映射處理。
c、常見的五種單例模式實現方式:
主要:-餓漢式(線程安全,調用效率高。但是,不能夠延時加載)
-懶漢式(線程安全,調用效率不高。但是,可以延時加載)
其他:-靜態內部類式(線程安全,調用效率高,可以延時加載)
-枚舉單例(線程安全,調用效率高,不能夠延時加載)
d、常見應用場景:
- Windows 的 Task Manager (任務管理器)就是典型的單例模式,你可以發現只能打開一個窗口。
- Windows 的 Recycle Bin(回收站)也會死典型的單例模式,在整個系統運行的過程中,回收站一直維護著僅有的一個單例。
- 項目中,讀取配置文件的類,一般也只有一個對象。沒有必要每次使用配置文件數據,每次 new 一個對象去讀取。
- 應用程序的日誌應用,一般都采用單例模式實現,這由於共享的日誌文件一直處於打開的狀態,因為只有一個實例去操作,否則內容不好追加。
- 數據庫連接池的設計一般也是采用單例模式,因為數據庫連接是一種數據庫資源。
- 在 Spring 中,每個 Bean 默認是單例的,這樣做的優點是 易於給 Spring 容器管理。
- 在 servlet 編程中, 每個 Servlet 也是單例的。包括 Application 對象也會單例的
3、餓漢式實現(單例對象立即加載)
a、代碼演示:
public class SinglenDemo01{
private static SinglenDemo0 s = new SinglenDemo01();
private SingletonDemo(){} // 構造器私有化,使外部不能夠調用
public static SingletomDemo01 getInstance(){
return s;
}
}
b、性能總結:
在餓漢式單例模式設計中,static 變量會在類裝載時初始化,此時也不會涉及多個線程對象訪問該對象的問題。虛擬機保證只會裝配一次該類,肯定不會發生並發訪問的問題。因此,可以省略 synchronized 關鍵字。
問題:如果只是加載該類,而並不需要調用getInstance(),甚至永遠沒有調用,則會造成資源浪費
4、懶漢式實現(單例對象延遲加載)
a、代碼演示:
public class SingletonDemo02{
private static SingletonDemo02 s;
private SingletonDemo02(){}
public static synchronized SingletonDemo02 getInstance(){
if(s == null){
s = new SingletonDemo01();
}
return s;
}
}
註:加入 synchronized 關鍵字,在多線程對象調用這個方式時,一個線程調用時,其他線程必須掛起,不允許調用這個方法,避免線程安全的問題。
b、優勢:延遲加載,在需要用到的時候再進行加載
劣勢:資源利用效率高了,但是每次調用 getInstance() 方法時都需要同步,並發效率較低。
5、靜態內部類實現方式(也是一種懶加載方式)
a、代碼演示:
public class SingletonDemo03(){
private static class SingletonClassInstance{
private static SingletonDemo03 instance = new SingletonDemo03();
}
private static SingletonDemo03 getInstance(){
return SingletonClassInstance.instance;
}
private SingletonDemo03(){
}
}
b、性能總結:
- 外部類沒有 static 屬性,則不會像餓漢式那樣立即加載對象。
- 只有真正調用 getInstance(),才會加載靜態內部類。加載類時是線程安全的。instance 是 static 類型,保證了內存中只有這樣一個實例存在,而且只能被賦值一次,從而保證線程安全性。
- 兼備了並發高效調用和延遲加載的優勢。
6、使用枚舉實現單例模式:
a、代碼演示:
public enum SingletonDemo04(){
//定義一個枚舉的元素,他就代表了 Singleton 的一個實例
INSTANCE;
//單例可以有自己的操作
public void singletonOperation(){
//功能處理
}
}
b、優點:實現簡單,枚舉本身就是單例模式。由 JVM 從根本上提供保障!避免通過反射和反序列化漏洞的問題。
缺點:無延時加載。
本文出自 “12392717” 博客,請務必保留此出處http://12402717.blog.51cto.com/12392717/1927890
23種設計模式介紹以及單例模式的學習