大多數做軟體設計的人都學習過設計模式,而看過《設計模式》那本書的人一定對單例模式有印象。在眾多的設計模式中,單例模式顯得很特別,清晰又簡單,容易被人記住,所以使用的也相當多。然而最近在乙個
c++的新專案中,發現了非常多的地方用了單例模式,幾乎到了濫用的地步,帶來的不好的地方也顯現了出來。本文總結一下單例模式的害處,與大家分享,也提醒一些初學設計模式的朋友:設計模式有限制,用錯了場景依然不是好的設計。
害處一,隱式依賴引起的結構不清晰
有的時候,你並不知道要使用的那個類
a是單例。當你讀類
b**的時候,你可能會先看它的標頭檔案,或
vc類檢視裡的內容,從這裡你無法知道b類和
a類的關係,因為
b類在實現的時候才使用
a類的那個所謂「
getinstance
」之類的函式,讀不到這一行,就不會知道
b類對依賴
a類的依賴關係。
害處二,多個例項的限制
有人可能會說了,單例就是防止多例項的,這算什麼害處呢?確實,但實際情況是,許多被定義成單例的類,並不是非得單例不可。有的人使用單例,只是為了在引用它的時候方便,把單例當個全域性變數一樣,拿過來就用,從而免去設定例項間引用關係的**。可是隨著專案的發展,麻煩可能會不期而至。比如:需要乙個新的
a類的例項來支援乙個新的功能場景,或者
b類需要在
a類的例項和另乙個類的例項中選擇乙個來實現功能。
害處三,單例類的擴充套件限制
單例類沒辦法通過繼承的方式擴充套件。因為那個
getinstance
靜態函式沒辦法生成子類的例項。如果你想給單例類擴充套件點介面,只有直接修改那個類了。想利用它來生成乙個更豐富的子類是不可能的。
害處四,程式結束時的記憶體洩漏
有些人認為程式都結束了,漏一點記憶體沒問題。但我不這麼認為。沒有正確析構的例項,漏的可能不只是記憶體,還有其它資源未釋放的危險。我所讀到的設計模式那本書上並沒有詳細描述例項釋放的問題,所以我看到很多人寫的單例**也沒有例項釋放控制這一段,這使記憶體洩漏成了必然結果。我在以前的部落格中討論過單例的釋放方法,叫《單例模式的釋放控制》,有興趣的朋友可以看一下。
以上主要是針對大多數單例模式的實現而言的。這些實現類似書《設計模式》那本書上的描述,保護的建構函式,
getinstance
得到例項。其它方法實現的單例不在本文的討論之列。
對說初學者來說,很難把握住「變化」。也許當初以為只有乙個例項,以後會有多個,這就會受到害處二的限制。以我的觀點來看,盡量不要用它,我們來有更多更明了的方式來建立兩個類的關係。
單例模式是一種限制性模式。如果你並不需要限制,就不要受
getinstance
方式獲取例項的**,它比全域性變數好不了多少。
濫用單例設計模式的害處
大多數做軟體設計的人都學習過設計模式,而看過 設計模式 那本書的人一定對單例模式有印象。在眾多 的設計模式中,單例模式顯得很特別,清晰又簡單,容易被人記住,所以使用的也相當多。然而最近在乙個 c 的新專案中,發現了非常多的地方用了單例模式,幾乎到了濫用的地步,帶來的不好的地方也顯現了出 來。本文總結...
什麼是單例模式?常見的單例模式寫法有哪些?
保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點。單例模式是一種常用的軟體設計模式之一,其目的是保證整個應用中只存在類的唯一乙個例項。餓漢式 單例模式 餓漢式 public class 01 方法沒有同步,呼叫效率高 public static 01 getinstance 懶漢式 單例模式 ...
什麼是單例模式?單例模式有哪些方式實現?寫個例子。
我所理解的單例模式 整個程式中只允許有唯一的乙個物件 這個類只能例項化一次 看看我找到的解釋 當乙個類只能有乙個物件時,往往會用到單例模式,例如,現實生活中有很多臨界資源,像 印表機 處理器 單核 皇帝 太子等等,它們都是稀有資源,只能有乙個例項物件。第一種最簡單,但沒有考慮執行緒安全,在多執行緒時...