慎用單例模式!


     一年前曾經非常開心的修改了QQ簽名,“酷愛單例模式”!
     經典設計模式書的第一講,這是個如此神奇的模式,比C里的全局變量看起來更有過之而無不及,在任何地方,只要引用了庫名稱,你就能獲得全局訪問點,隨時修改隨時讀取,豈不爽哉?
     於是,在一段時間內,我把我非常重要的幾個實體類都用單例模式實現了,任何地方都可訪問,解決了好多大難題!
     但,越到后來,越隱隱約約的發現,單例是個笑面殺手!
 
     對程序架構而言,單例意味着沒有隱藏,插入到程序的任何組件都可以隨時修改它,這客觀上違背了面向對象的最小公開法則,程序健壯性安全性驟降。
     對程序擴展性而言,單例意味着很難被繼承重寫!  當你在一個單例中嘗試覆蓋它的某些功能時,編譯器會報錯,這時候你哭去吧。或者,你會奇怪的發現,咦?怎么還是基類的功能!
     對程序邏輯而言,單例,顧名思義,僅有其一,但你的程序在發展着,你確定只有一個實例即可?某天突然發現,業務變了,需要擴展,那些數不清的用單例調用的代碼怎么處理?尤其是已經發布到顧客手中的代碼?
     對效率而言,每次訪問它的時候,都會查看是否被創建(多增加了一次判斷),這對於一些需要高性能的程序是非常不合適的。
     對多線程而言,在多線程環境下,實現單例是需要技巧的。否則,單例不單!
     對對象生命周期而言,單例只有自己持有真正的引用,,如何銷毀何時銷毀都是問題,可能還會造成指針懸掛。
     對開發者而言,一個類不能new! 這還會帶來更多的疑問和混淆。
 
     於是,我便站在了這樣的十字路口,要么花大力氣重寫核心代碼,要不延續單例模式的老路,再痛苦幾年。
     痛定思痛, 我決定改掉那個模式。 大概,單例是個真正需求較窄的設計模式,僅僅適合設計配置參數上管理類,或者調試輸出類(大家司空見慣的Log),或者是一些全局訪問但功能相對單一的功能,千萬別嘗試將單例包裝到復雜的數據實體上,這樣做只是飲鴆止渴,哪天回過頭來,就像操作系統的注冊表一樣,又臭又長,帶來的危險比帶來的好處還多得多!
     有一期“程序員”雜志刊登了一篇采訪 GoF(設計模式作者)的文章,他們計划對<設計模式>進行修訂,其中還特別提到要剔除“單例模式”,認為單例模式很容易在系統中產生“代碼的臭味”,期待新版的設計模式早點出來。
     共勉。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM