2015-04-30 31 views
0

我已經在WPF中啓動了一個小應用程序,並使用一個Singleton類來處理所有的應用程序邏輯。另外,我還有一些ObservableCollections綁定到View上的DataGrid。如何重構單例類,避免再犯同樣的錯誤

問題:本來應該是一個小程序開始增長的功能和代碼現在太難以維護,重用,並有高水平的代碼耦合。

所以我開始將代碼移動到其他類。例如,我有一個只處理文件讀數的類。我使這個類成爲靜態的,因爲我只運行一次這些方法(當我需要將數據導入到數據庫時),並且當它們結束時,我不再需要這些對象,只是忘記它們存在。

現在我正在考慮對其他方法進行相同的操作,例如從數據庫檢索數據的方法。

我的疑問是,如果那是解決問題的正確方法?恐怕使用靜態類將會像單身人士的乘法一樣。

+0

你最初試圖通過使用Singleton來解決什麼問題? – DGibbs

+0

當時我沒有特別開始。但是當你需要顯示結果(一個正在運行的程序和正在做的事情),並且你需要有很多窗口時,每一個類中都有相同對象的類只是方便而且快速地顯示功能。 – celsoap7

回答

1

靜態類被一些人認爲是邪惡的,但這只是一個意見。當我有這些問題時,我會看看.NET框架:它在那裏如何解決?

有時單身可以被重構爲靜態類。這取決於實際情況。如果您的單例類型是繼承(讀取:必須繼承)其他類或接口的類型,則它不能轉換爲靜態類,因爲靜態類不能繼承任何東西。

如果您創建一個靜態類,儘量遵循以下規則:(這些規則也由.NET Framework服從):

  • 所有靜態成員必須是線程安全的。

就是這樣! :)

規則聽起來簡單,但蘊涵着很多:

  • 所有的靜態成員的工作相互獨立的。因此,一次呼叫不會影響另一次呼叫的結果。
  • 靜態類不允許維護(靜態)狀態。
  • 如果該類有靜態字段,請確保它們是隻讀或常量。確保這些字段的內容永不改變。

當然可能會有一些小例外。例如:一個靜態類可以維護一個內部字典來緩存結果。修改此緩存必須是線程安全的。既然它是內在的東西,對外界來說,靜態類仍然服從上述規則。

所以......簡而言之:如果你的單例不是線程安全的(保存狀態等),不要將它轉換爲靜態類。

*編輯*

使用單通常意味着你必須包含某種類型的一個實例的靜態屬性。由於這是一個靜態屬性,它也必須遵守上述規則,這意味着該實例必須是線程安全的。

如果您的(單例)實例不是線程安全的,請重新設計您的應用程序,使其不使用此單例或靜態類。讓所有代碼在需要時創建此類的新實例。

+0

只有我的單例的某些部分是線程安全的,例如我讀取一個文件,將數據發送到數據庫並完成。沒有什麼是必要的。你如何看待靜態類返回數據,如列表? – celsoap7

+0

返回數據的靜態方法完全沒問題。例如:'System.IO.Directory.GetFiles(...)'(https://msdn.microsoft.com/en-us/library/07wt70x2(v=vs.110).aspx) –

+0

但由於只有部分你的單身人士是線程安全的(換句話說,有些部分不是),不要這樣做! –