3 回答

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

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