設計模式 單例模式

2022-05-07 00:51:11 字數 2841 閱讀 6784

單例模式( singleton pattern) 是乙個比較簡單的模式, 其定義如下:

ensure a class has only one instance, and provide a global point of access to it.( 確保某乙個類只有乙個例項, 而且自行例項化並向整個系統提供這個例項。 )

單例類, 通過構造私有化確保了在乙個應用中只產生乙個例項, 並且是自行例項化的( 在singleton中自己使用new singleton()) 。

class

singleton

private

:

static singleton*p;

public

:

static singleton*instance();

};singleton* singleton::p =null;

singleton*singleton::instance()

這種模式不是執行緒安全的,如果執行緒a和執行緒b同時呼叫instance,那麼兩個執行緒都會建立乙個示例,這明顯是不對的。

不到萬不得已就不會去例項化類,也就是說在第一次用到類例項的時候才會去例項化,所以上邊的經典方法被歸為懶漢實現;

經過上面的演示,明顯懶漢模式是執行緒不安全的。那麼怎麼保證執行緒安全呢?加鎖!

加鎖的經典模式

class

singleton

private

:

static singleton*p;

public

:

static

pthread_mutex_t mutex;

static singleton*initance();

};pthread_mutex_t singleton::mutex;

singleton* singleton::p =null;

singleton*singleton::initance()

return

p;}

內部靜態變數的懶漢實現

此方法也很容易實現,在instance函式裡定義乙個靜態的例項,也可以保證擁有唯一例項,在返回時只需要返回其指標就可以了。

class

singleton

public

:

static

pthread_mutex_t mutex;

static singleton*initance();

};pthread_mutex_t singleton::mutex;

singleton*singleton::initance()

餓了肯定要飢不擇食。所以在單例類定義的時候就進行例項化。

class

singleton

private

:

static singleton*p;

public

:

static singleton*initance();

};singleton* singleton::p = new

singleton;

singleton*singleton::initance()

為什麼說餓漢模式是執行緒安全的呢?因為靜態例項初始化在程式開始時進入主函式之前就由主線程以單執行緒方式完成了初始化,不必擔心多執行緒問題。

由於要進行執行緒同步,所以在訪問量比較大,或者可能訪問的執行緒比較多時,採用餓漢實現,可以實現更好的效能。這是以空間換時間。

在訪問量較小時,採用懶漢實現。這是以時間換空間。

由於單例模式在記憶體中只有乙個例項, 減少了記憶體開支, 特別是乙個物件需要頻繁地建立、 銷毀時, 而且建立或銷毀時效能又無法優化, 單例模式的優勢就非常明顯。

由於單例模式只生成乙個例項, 所以減少了系統的效能開銷,

當乙個物件的產生需要比較多的資源時, 如讀取配置、 產生其他依賴物件時, 則可以通過在應用啟動時直接產生乙個單例物件, 然後用永久駐留記憶體的方式來解決。

單例模式可以避免對資源的多重占用,

例如乙個寫檔案動作, 由於只有乙個例項存在記憶體中, 避免對同乙個資源檔案的同時寫操作。

單例模式可以在系統設定全域性的訪問點,

優化和共享資源訪問, 例如可以設計乙個單例類, 負責所有資料表的對映處理。

單例模式一般沒有介面, 擴充套件很困難, 若要擴充套件, 除了修改**基本上沒有第二種途徑可以實現。 單例模式為什麼不能增加介面呢? 因為介面對單例模式是沒有任何意義的, 它要求「自行例項化」, 並且提供單一例項、 介面或抽象類是不可能被例項化的。 當然, 在特殊情況下, 單例模式可以實現介面、 被繼承等, 需要在系統開發中根據環境判斷。

單例模式對測試是不利的。 在並行開發環境中, 如果單例模式沒有完成, 是不能進行測試的, 沒有介面也不能使用mock的方式虛擬乙個物件。

單例模式與單一職責原則有衝突。 乙個類應該只實現乙個邏輯, 而不關心它是否是單例的, 是不是要單例取決於環境,

單例模式把「要單例」和業務邏輯融合在乙個類中。

在乙個系統中, 要求乙個類有且僅有乙個物件, 如果出現多個物件就會出現「不良反應」, 可以採用單例模式, 具體的場景如下:

要求生成唯一序列號的環境;

在整個專案中需要乙個共享訪問點或共享資料, 例如乙個web頁面上的計數器, 可以不用把每次重新整理都記錄到資料庫中, 使用單例模式保持計數器的值,

並確保是執行緒安全的;

建立乙個物件需要消耗的資源過多, 如要訪問io和資料庫等資源;

需要定義大量的靜態常量和靜態方法( 如工具類) 的環境, 可以採用單例模式(

當然, 也可以直接宣告為static的方式) 。

設計模式 單例模式

單例模式 singleton pattern 是乙個比較簡單的模式,其定義如下 ensure a class has only one instance,and provide a golbal point of acess to it.確保某乙個類只有乙個例項,而且自行例項化並且向整個系統提供這個...

設計模式 單例模式

class testsingleton static public function instance return self testsingleton private function clone public function setsinvar sinvar public function ...

設計模式 單例模式

單例模式的目的是保證類在系統中只被例項化一次,由該唯一的例項來為系統提供服務.單例模式主要用於保證服務的統一,比如獲取統一的編號服務,模仿oracle的序列生成等.但單例的使用需要謹慎,特別是在需要作負載均衡的地方,因為這種程式級的單例模式實際上只能保證在乙個應用中為單例.如果被多個應用載入,還是會...