[英]How can I safely convert a static class to an instantiated class in C#
我最近(幾個月前)改變了工作,繼承了一個代碼庫,它違反了SOLID原則的每一個,盡可能多次。 似乎編寫此代碼的人決定詳細研究每一個良好的編碼實踐,並盡可能經常地和最根本地違反它們。
我是該產品的唯一開發人員 - 組織中沒有人知道代碼,代碼庫太大而且復雜,無法完全重寫。 我正在研究可以使代碼庫變得靈活和健壯的最高價值變化。 放棄此產品也不是一種選擇。
產品中所有問題的根源於一組類,這些類是核心業務邏輯數據結構。 這些類有很多問題,但我真正感興趣的是以下內容:
public static class NetCollection
{
private static Logger LogFile { get { return Logger.GetMethodLogger(2); } }
// Declare local variables.
private static Dictionary<string, NetObject> netObjectHashTable;
private static Dictionary<string, NetTitle> titlePropertyHashTable;
private static Dictionary<string, NetObject> referenceDataHashTable;
private static Dictionary<int, SortedDictionary<string, int>> picklistHashTable;
public static IEnumerable<NetObject> NetObjects
{
get
{
return netObjectHashTable.Values;
}
}
static NetCollection()
{
netObjectHashTable = new Dictionary<string, NetObject>();
titlePropertyHashTable = new Dictionary<string, NetTitle>();
referenceDataHashTable = new Dictionary<string, NetObject>();
picklistHashTable = new Dictionary<int, SortedDictionary<string, int>>();
}
public static void AddNetObject(NetObject newObject)
{
if (newObject == null)
return;
if (newObject.TitleType == "Reference Data")
{
// Check if hash table contains key
if (!referenceDataHashTable.ContainsKey(newObject.ID.ToString()))
{
referenceDataHashTable.Add(newObject.ID.ToString(), newObject);
}
}
else
{
// Check if hash table contains key
if (!netObjectHashTable.ContainsKey(newObject.ID.ToString()))
{
netObjectHashTable.Add(newObject.ID.ToString(), newObject);
}
}
}
}
為了簡潔起見,我已經從這個類中剪切了很多其他方法。
正如你所看到的,這個類周圍存在大量問題(在靜態類中存儲狀態是一個巨大的代碼味道 - 圍繞所述類編寫整個應用程序只是瘋了)。
我目前的意圖是將這個類重構為一個合適的單例類(並最終進入一個常規類,這樣我就可以讓用戶同時打開多個文檔)。
我應該這樣做嗎?
進行此項更改的最大風險是什么? 我是否可以采取任何方法來降低進行此更改的風險?
是的,轉換為單身似乎是一個良好的第一步。 它仍然不是線程安全的,但它是一個開始。 然后,您可以將其從真正的單例更改為允許構造單獨實例的單例,但也可以像單例一樣使用“默認”實例。 (當然,你可以將“實例持有者”分成一個單獨的類。)這將允許你開始編寫可測試代碼,每次都以一個新實例開始。
之后,您可以開始引入依賴注入,以便需要訪問同一實例的每個類獲取它...並刪除“默認”實例。
當然,如果你可以減少需要訪問同一個實例的類的數量,那也會更好。
對於線程,您需要鎖定每個方法,或使用ConcurrentDictionary
。
如果您對應用程序中此類型的流程一無所知,那將是一項危險的任務。 但如果你真的需要這樣做,可能會打破一切,我會這樣做:
知道我需要的是文檔之間的明顯划分,我知道(這已經證明了時間)這種類型適用於單個文檔,讓我們添加Document slice。
假設Document
有Name
屬性,我們可以考慮像(例子)這樣的東西:
public static void AddNetObject(string documentName, NetObject newObject)
{
....
}
使所有字段非靜態:
//NO STATIC
...
private Logger LogFile { get { return Logger.GetMethodLogger(2); } }
private Dictionary<string, NetObject> netObjectHashTable;
private Dictionary<string, NetTitle> titlePropertyHashTable;
private Dictionary<string, NetObject> referenceDataHashTable;
private Dictionary<int, SortedDictionary<string, int>> picklistHashTable;
將它們移動到內部
private class NetDocument {
public string DocumentName {get;set;} //DEFINE DOCUMENT IT RELATED TO !
...
private Logger LogFile { get { return Logger.GetMethodLogger(2); } }
private Dictionary<string, NetObject> netObjectHashTable;
....
}
因此,您可以在單個文檔之間創建具體的隔離,並與它們相關。
在主類里面后你可以有:
public static class NetCollection
{
...
//Key: document name
//Value: NetDocument data
private Dictionary<string, NetDocument> documents = new ....
}
這只是一個概念(草圖),您肯定需要根據自己的需要進行更改 。
你可以將它包裝在一個靜態的Factory類中嗎? 制作你認為自己需要的所有單件,並根據需要保持某些東西靜止? 它將解決一些問題,並為您提供一些靈活性。
static
類和Singleton之間沒有真正的區別。 是的,它的實現方式不同,但你有同樣的問題(只是為了沒有static
我不認為這是必要的行為)。
如果你能夠找到“真實”的實例,那就去做吧。 但只是重構單身,因為林特不抱怨不是恕我直言的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.