1. 程式人生 > >23種設計模式介紹以及單例模式的學習

23種設計模式介紹以及單例模式的學習

單例模式 餓漢式 23種設計模式 gof23

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種設計模式介紹以及單例模式的學習