web-dev-qa-db-ja.com

switchステートメントの代わりにアクション辞書を使用する

古いコードの一部を確認しているところですが(時間があります)、かなり長いswitchステートメントに気づきました。新しい知識を得たため、私はそれを次の形式でリファクタリングしました。

private Dictionary<string, Action> createView
    {
        get
        {
            return new Dictionary<string, Action>()
            {
                {"Standard", CreateStudySummaryView},
                {"By Group", CreateStudySummaryByGroupView},
                {"By Group/Time", CreateViewGroupByHour}
            };
        }
    }

これは良い習慣だと思いますか、それとも単に不必要で不必要な場合ですか?私が学んだ新しいテクニックが、それのためだけに巧妙ではなく、実際にコードに利益をもたらすことを確実にすることに熱心です。

ありがとう。

24
Darren Young

長いswitchステートメントは古典的な悪臭であり、常にリファクタリングの対象になります。

ここで実行する「標準」ステップは 条件付きをポリモーフィズム に置き換えます。これは、Martin Fowlerの本 リファクタリング (11年前の1999年に発行)に記載されている手順の1つでした。

関数をオブジェクトのように扱うのがとても簡単になったので(たとえばActionを使用)、これは同じように良い解決策かもしれません。

いいえ、あなたがそれのために賢いとは思わない。将来、別のオプションを追加したい場合は、何をする必要があるかを簡単に確認できます。

19
Andrew Shepherd

アプリによっては、常に新しい辞書オブジェクトを作成することを回避できますが、クラスメンバーのように宣言し、最初のアクセスで初期化し、常に同じインスタンスを返します。しかし、それが実際にあなたのニーズに合うかどうかを言うのは難しいです。このように私は意味します

public class MyClass 
{
   Dictionary<string, Action> dict = null; 

    private Dictionary<string, Action> createView
    {
        get
        {
            if(dict  == null) 
            {
              dict  = new Dictionary<string, Action>()
              {
                {"Standard", CreateStudySummaryView},
                {"By Group", CreateStudySummaryByGroupView},
                {"By Group/Time", CreateViewGroupByHour}
              };
            }

            return dict;
        }
    }

}

[〜#〜]編集[〜#〜]

conceptualの観点から、長いswicth/caseを辞書TryGetValueに置き換えるのはかなり良い解決策です。

お役に立てれば...

9
Tigran

このアプローチは優れています。

Action以外にも使用しています。フィルタやセレクターにも非常に効果的です。何かのようなもの:

var filters = new Dictionary<string, Func<MyEntity, bool>>()
{
    // ...
};

var query = entities.Where(filters["X"]);
5
Enigmativity

一度記述されたコードがほとんど静的であり、あまり変更されない場合は、switchに固執しているでしょう。ここでの辞書のアプローチは、少なくとも表面的には、より動的であることに適しています。ただし、要件に基づいています。

このアプローチを使用して、あらゆる場所のスイッチをコードに置き換えることに関しては、私はほとんどの場合、個人的にはそうしません。私の正直な意見は、それのために賢いだけだろうということですが、それでも簡単に保守できます。私が見ているように、ここではベストプラクティスよりも個人的な好みが最大の要因です。

一方、他の人が言っているように、これは長いswitchステートメントに対する実行可能な解決策になる可能性があります。次に、 Strategy Pattern のようなものも、動作の変更をサポートするための良い方法です。

2