2

戦略パターンに置き換えたい巨大な switch/case ステートメントがあります。各ステートメントには、特定のロジックを実行するコードの大きな平和があります。そのような場合にパターンを使用する良い例はありますか、またはこれに対する他の良い解決策はありますか?

私のソリューションソファー

class Context
{
    private readonly List<CalculationUnit> _calculationsUnits;

    public Context()
    {
        _calculationsUnits = new List<CalculationUnit>()
                                 {
                                     new CalculationUnitA("calc1"),
                                     new CalculationUnitB("calc2"),
                                     new CalculationUnitC("calc2")
                                 };
    }

    public int Calculate(string name)
    {
        return (from c in _calculationsUnits where c.Name.Equals(name) select c.Calculate()).FirstOrDefault();
    }
}

class CalculationUnit
{
    public string Name { get; private set; }

    public CalculationUnit(string name)
    {
        Name = name;
    }

    public virtual int Calculate()
    {
        return 0;
    }
}

class CalculationUnitA : CalculationUnit
{
    public CalculationUnitA(string name) : base(name) { }

    public override int Calculate()
    {
        //calculations logic A
    }
}

class CalculationUnitB : CalculationUnit
{
    public CalculationUnitB(string name) : base(name) { }

    public override int Calculate()
    {
        //calculations logic A
    }
}

class CalculationUnitC : CalculationUnit
{
    public CalculationUnitC(string name) : base(name) { }

    public override int Calculate()
    {
        //calculations logic A
    }
}

しかし、その後、各ロジックを実装する 50 個のクラスになってしまいます...

ありがとう

4

1 に答える 1

8

戦略パターンは、各ブランチの大きなコードを個別のクラス(またはメソッド)にリファクタリングすることで、ここで役立ちます。次に、スイッチは適切なストラテジークラス(またはメソッドデリゲート)を選択するだけのケースになり、スイッチステートメントの最後に1回の呼び出しで実行されます。したがって、大まかに次のようなものです。

switch (...)
{
    case ...:
        // Horrible logic;
        break;
    ...
}

次のようになります:

ILogicImplementer implementer;
switch (...)
{
    case ...:
        implementer = new FirstCaseImplementer();
        break;
    ...
}
implementer.Implement();

ロジックをリファクタリングして、共通のインターフェイスを実装する(または共通の基本クラスを拡張する)一連のクラスにするか、互換性のある署名を持つ一連のメソッドにリファクタリングして、一致するデリゲートを選択する戦略を立てる必要があります。Odedが彼のコメントで示唆しているように、必ずしもこれを取り除くつもりはありませんselectが、それぞれのケースははるかに小さくなります。

簡単な説明から、コードをより単純で保守しやすくするための適切なアプローチのように聞こえます。

于 2012-05-18T09:23:08.010 に答える