5

私は最近 (数か月前) 転職し、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);
            }
        }
    }
}

簡潔にするために、このクラスからかなりの数の他のメソッドを抜粋しました。

ご覧のとおり、このクラスには膨大な数の問題があります (静的クラスに状態を保存するのはコードの匂いがします。このクラスを中心にアプリケーション全体を作成するのは、まったくおかしなことです)。

私の現在の意図は、このクラスを適切なシングルトン クラスに (最終的には通常のクラスに) リファクタリングして、ユーザーが複数のドキュメントを同時に開くことができるようにすることです。

これを行う必要がありますか?

この変更を行う際の最大のリスクは何ですか? この変更を行うリスクを軽減するために講じることができるアプローチはありますか?

4

4 に答える 4

4

はい、シングルトンへの変換は良い最初のステップのようです。まだスレッドセーフではありませんが、それが始まりです。次に、それを真のシングルトンから、個別のインスタンスを構築できるものに変更できますが、シングルトンと同じ方法で「デフォルト」インスタンスも持ちます。(もちろん、「インスタンス ホルダー」を別のクラスに分離することもできます。) これにより、毎回新しいインスタンスで始まるテスト可能なコードを書き始めることができます。

その後、依存性注入の導入を開始して、同じインスタンスへのアクセスが必要な各クラスがそれを取得できるようにし、「デフォルト」インスタンスを削除します。

もちろん、同じインスタンスにアクセスする必要があるクラスの数を減らすことができれば、それもより良いでしょう。

スレッド化するには、各メソッドをロックするか、ConcurrentDictionary.

于 2013-07-18T07:16:17.547 に答える
2

このタイプがアプリケーション内でどのように流れるかについて何も知らない場合、それは危険な作業です。しかし、おそらくすべてを壊さずにそれを行う必要がある場合は、次のようにします。

私が必要としているのはドキュメント間の明確な区分であり、このタイプが単一のドキュメントに対して機能することを知っている (時間によって証明されている) ことを知っているので、Document スライスを追加しましょう。

DocumenthasNameプロパティがあると仮定しましょう。(例):

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

これは単なる一般的なアイデア (スケッチ) であり、ニーズに合わせて変更する必要があります

于 2013-07-18T07:19:34.273 に答える
0

これを静的な Factory クラスにラップできますか? 必要と思われるものはすべてシングルトンにして、必要に応じて特定のものを静的に保ちますか? これにより、いくつかの問題が解決され、ある程度の柔軟性が得られます。

于 2013-07-18T07:15:41.680 に答える
0

staticクラスとシングルトンの間に実際の違いはありません。はい、実装は異なりますが、同じ問題があります(そして、持っていないという理由だけで、static行動する必要はないと思います)。

「実際の」インスタンスに行くことができる場合は、それを実行してください。しかし、リントが文句を言わないのでシングルトンにリファクタリングするだけでは、私見に行く方法ではありません。

于 2013-07-18T07:18:55.653 に答える