3 回答

TA貢獻1804條經驗 獲得超7個贊
是的,單身人士很糟糕。它們很糟糕,因為它們為你所做的只是結合了兩個屬性,每個屬性在95%的時間都是壞的。(這意味著平均而言,單身人士在99.75%的時間里表現不佳;))
由GoF定義的單例是一種數據結構:
授予對象的全局訪問權限
強制只能存在一個對象實例。
第一個通常被認為是一件壞事。我們不喜歡全局變量。第二個是更微妙,但一般來說,實際上沒有任何情況下這是一個合理的強制執行限制。
有時,只有一個對象實例才有意義。在這種情況下,您選擇只創建一個。您不需要單例來強制執行它。
通常情況下,即使只有一個實例“有意義”,事實證明它根本沒有意義。遲早,你需要不止一個記錄器?;蛘叨鄠€數據庫?;蛘吣鷮⒉坏貌粸槊總€單元測試重新創建資源,這意味著我們必須能夠隨意創建它們。在我們理解后果之前,它過早地從我們的代碼中消除了靈活性。
單例隱藏依賴關系并增加耦合(每個類都可能依賴于單例,這意味著除非我們還重用所有單例,否則該類不能在其他項目中重用),并且因為這些依賴關系不是立即可見的(作為函數/構造函數參數) ),我們沒有注意到它們,通常在我們創建它們時不會考慮它們。只需拉入一個單例就可以了,它幾乎就像一個局部變量一樣,所以我們傾向于在它們存在時使用它們很多。這使他們幾乎不可能再次刪除。你最終,也許不是意大利面條代碼,而是意大利面依賴圖。遲早,你失控的依賴關系將意味著單身人士開始依賴彼此,然后在嘗試初始化時獲得循環依賴關系。
他們使單元測試非常困難。(如何測試在單個對象上調用函數的函數?我們不希望運行實際的單例代碼,但是我們如何防止這種情況?
是的,單身人士很糟糕。
有時,你真的想要全球化。然后使用全局而不是單身。
有時,非常非常非常罕見,你可能有一種情況,創建一個類的多實例是一個錯誤,它可以沒有導致錯誤進行。(關于我能想到的唯一一個案例,即使這是設計的,如果你代表一些硬件設備。你只有一個GPU,所以如果你要將它映射到代碼中的一個對象,它會理解只有一個實例可以存在)。但是,如果您發現自己處于這種情況(并且再次強調,多個實例導致嚴重錯誤的情況,而不僅僅是“我無法想到多個實例的任何用例”),那么執行該約束,但不要使對象全局可見。
每個這兩個屬性可以是有用的,在極少數情況下。但我想不出一個案例,他們的組合將是一件好事。
不幸的是,很多人都認為“Singletons是符合OOP標準的全局變種”。不,他們不是。除了介紹其他一些完全不相關的問題之外,他們仍然遇到與全局問題相同的問題。絕對沒有理由比普通的全球更喜歡單身人士。

TA貢獻1847條經驗 獲得超7個贊
軟件開發人員似乎分成兩個陣營,這取決于他們是贊成理想主義的編碼風格還是實用的編碼風格:
理想主義:永遠不要使用單身模式。
務實:避免單身模式。
就個人而言,我贊成務實的做法。有時違反規則是有道理的,但前提是你真正了解自己在做什么,并愿意接受相關的風險。如果您對以下關于特定用例的問題回答“是”,則單例模式可以產生一些實際好處。
單身是你的應用程序的外部嗎?數據庫,排隊服務和ESB都是單例模式的完全有效的宏示例。
KISS:你的整個應用僅限于2-3個內部單身人士嗎?
DRY:那些單身人士本身是否具有全球性,因此不得不在你的應用程序中幾乎每個對象中引用參考文獻?(例如,記錄器或組件介體)?
您的單身人士是否僅依賴于彼此和/或操作環境?
您是否確保了每個單例的正確啟動和關閉順序,包括內存管理注意事項?例如,“Grand Central”樣式的線程池可能需要在main()中具有實例Run()和Shutdown()方法,以便保證任務僅在它們操作的對象處于有效狀態時運行。
- 3 回答
- 0 關注
- 692 瀏覽
添加回答
舉報