2011-12-19 61 views
2

已經是asked單身課程和靜態課程有什麼區別。但是,瞭解其中的差異,每次我需要選擇時,我仍然感到困惑。單身和靜態課程案例研究

所以對於我自己我定義了兩種不同的情況 - 如果應該只有這個類的一個實例(這是很少的)和所有服務類的靜態類,我使用POJO類(在java中)主要是singletones這經常發生)。

例如,在我的應用程序中,我需要存儲消息(我有一個可序列化的類消息),將它們寫入文件,從文件中讀取並在運行時訪問。我沒有看到有任何理由在這裏使用單例,靜態類只是沒關係。唯一的靜態類是MessageStorage,它有3個函數 - 讀,寫和getMessages,還有一個靜態的私有數組列表。

這種方法是否合理?如果不是,它的問題是什麼?

+2

全局狀態/靜態通常被認爲是不好的形式,這就是爲什麼單例經常被認爲是[反模式](http://en.wikipedia.org/wiki/Singleton_pattern#Drawbacks)。 「好的做法」是靜態類和單例只能用於沒有狀態的輔助方法(例如'Math.sqrt(4)')。 – Bringer128 2011-12-19 03:19:56

+0

所以在這種情況下,你會怎麼做? – Sergey 2011-12-19 03:21:49

+0

在你需要存儲狀態的情況下,你只需要一個對象的引用。它不能由singleton模式保證,而是在任何需要這些信息的全局可達的位置。它會達到同樣的效果,但正如我在我的文章中所說的,差異在於可擴展性和可變性隨着需求的變化而改善。一旦創建一個類實現了singelton的目標,你需要做的就是在全球可以找到的地方引用它。 – Dessus 2011-12-19 04:12:49

回答

1

使用Java中的「單身」的兩個主要原因是:

1)因此,一些存儲可以用其他方式「靜態」類關聯。

2)對於給定服務的不同子類(或接口實現),您可能有多個「單例」,並且單例作爲標識要使用的特定服務的方式傳遞。

當然,代替#1,您可以使用「靜態」類的靜態字段來包含數據,但通常更方便(並且在很多情況下更有效)使主題的單個實例類包含數據,而多個靜態成員是其他類的實例。

而且,在#2的JDK中,有一個類實際上實現了多個「singletons」,它們定義了「常量」。 (例如,java.awt.font.TextAttribute。)

一般來說,Java中的單身人士的動機少於基於C的語言,因爲Java確實實現了真正的類關聯(和類保護)靜態數據,相對於在C語言中隱藏的僞裝(如果僞裝的話)全局靜態,所以人們可以簡單地在一個類中有多個靜態字段,而需要有一個「中心」對象來包含C語言中的字段。

1

:-)

  • MessageStore理想的設計應是這樣的接口
  • MessageStoreFactory應與一個getMessageStore()方法的單(如果getMessageStore()每次返回相同的消息存儲,也就是不是問題,你有你的單身人士)。
  • 然後你可以有多個MessageStore實現,如FileMessageStore,JDBCMessageStore,SubversionMessageStore,等...
  • 更重要的是,你可以有MockMessageStore,模擬出消息存儲,並能夠測試依賴於消息組件獨立於消息存儲存儲(並隔離任何故障)。例如,如果您正在測試MessageView併發生錯誤,則可以確定錯誤出現在MessageView中,而不是在您的靜態MessageStore中,因爲MockMessageStore是正確的。

這就是時尚的年輕人現在都在做天,反正...和依賴注入,而不是一個工廠,但

+0

依賴注入+1 – Dessus 2011-12-19 03:40:44

1

真正明白這裏的事情之一一步來......是有是c#/ java的不同內存組。

所有的類都將被加載到稱爲類加載程序內存的一段內存中。如果你創建了一個靜態的東西,它將保留在類加載器的內存中。它可以從那裏使用,但只能有1個實例。沒有類加載器內存的垃圾收集器,所有內容都在應用程序的整個生命週期中停留。

創建一個類的實例,無論它是否是單例,都意味着完成了內存拷貝,將類從類加載器內存中複製並將其複製到存儲實例的區域。實例可以被垃圾收集。

單和靜態類的選項之間的實際決策點是:

1)你想繼承,或爲你的類接口(如果是的話,你想單)
2)是否有意義強迫你的類有一個與你的應用程序相同的生命週期(也就是說,你必須手動清除這個類或者寫一個方法來完成它,這樣可以增加代碼,從而減少可維護性)。 (如果它不是那麼你想單身)
3)你的應用程序是否需要可擴展性和潛在的變化。現在單身人士通常被認爲是反模式,如果通過靜態屬性來實現。原因在於您投資於基礎設施,比如在您的類中暴露靜態實例屬性,這可能完全不是您將來想要的,因爲您的單個窗口應用程序可能突然變成多窗口,並且您需要重寫代碼。 (重寫代碼表示設計不好,尤其是如果其核心基礎設施)。

根據經驗,一般情況下,我想提出以下建議:

  • 任何類,那裏有一流的範圍變量,這應該是一個單身(因爲需要對潛在的擴展出來)。
  • 每個方法獨立的任何類應該是靜態的。