如何在C#中安全地将静态类转换为实例化类

Ste*_*hen 5 .net c# architecture

我最近(几个月前)改变了工作,继承了一个代码库,它违反了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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为了简洁起见,我已经从这个类中剪切了很多其他方法.

正如你所看到的,这个类周围存在大量问题(在静态类中存储状态是一个巨大的代码味道 - 围绕所述类编写整个应用程序只是疯了).

我目前的意图是将这个类重构为一个合适的单例类(并最终进入一个常规类,这样我就可以让用户同时打开多个文档).

我应该这样做吗?

进行此项更改的最大风险是什么?我是否可以采取任何方法来降低进行此更改的风险?

Tig*_*ran 2

如果您对这种类型如何在应用程序中流动一无所知,那么这是一项危险的任务。但如果你真的需要在不破坏一切的情况下做到这一点,我会喜欢:

知道我需要的是文档之间的不同划分,并且我知道(时间证明了)这种类型适用于单个文档,让我们添加文档切片。

假设DocumentName属性,我们可以考虑类似的事情(示例):

public static void AddNetObject(string documentName, NetObject newObject)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

使所有字段静态:

   //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;
Run Code Online (Sandbox Code Playgroud)

将它们移至内部

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;
       ....

  }
Run Code Online (Sandbox Code Playgroud)

因此,您可以在单个文档和与其相关的数据之间创建具体的隔离。

进入主类后,您可以:

public static class NetCollection
{
    ... 

    //Key: document name
    //Value: NetDocument data
    private Dictionary<string, NetDocument> documents = new ....
}
Run Code Online (Sandbox Code Playgroud)

这只是一个总体想法(草图),您肯定需要更改它以满足您的需求

  • 保留(只要可能)公共方法,以便外界的方法按原样看到您的类型内部。这将帮助您不更改所有调用者代码,因此可能会在类*内部*实现上造成混乱和榕树。我再说一遍,这是一个指南,是要走的路,但你会遇到问题(可以将所有公共方法保留原样,某些类型的可见性问题,100 多个其他东西..),所以只需继续一个简单的想法:不要触摸其他人可见的内容并更改该类型的*内部*行为。因此,所有可用的调用者将继续以相同的方式调用它,就像以前一样。 (2认同)