1

内部の情報をさらに洗練する列挙値であるeventargsオブジェクトを内部で受け取るイベントハンドラーがあります。それは次のように見えます

public enum StatusCallbackType { Status1, Status2, Status3, Status4 }

public class StatusEventArgs
{
  public StatusCallbackType Type {get;set;}
  public StatusData Data {get; set;}
}

Statusdataは、指定されたCalllbackTypeに応じて変化する基本抽象クラスです。

これで、イベントを処理するコードは次のようになります。

switch e.Type
{
  case Status1:
    DoAction1(e.Data as Opt1Data);
    break;
  case Status2:
    DoAction1(e.Data as Opt2Data);
    break;
  case Status3:
    DoAction1(e.Data as Opt3Data);
    break;
}

問題は、StatusNotificationsを変更したり、処理方法を変更したりする場合、非常に大きくなる可能性のあるスイッチを調整する必要があることです。特定のステータスのハンドラーを挿入できるものを使用することを考えていました。

一方で、今は本当に必要ありません。スイッチソリューションは機能しますが、大きくなり始めているので、メインタンブルではないという気持ちとYAGNIの間で戦っています。

そのようなスイッチをIOCパターンに変換できるパターンはありますか?そのスイッチを実際にリファクタリングする必要があると思いますか?

4

3 に答える 3

2

責任の連鎖パターンにリファクタリングできると思います。各switchステートメントは、通知を処理するか、通知が次のステートメントに渡されるコレクション内のハンドラーオブジェクトになります。

インジェクションに関しては、クライアントコードを変更せずにハンドラーの数を変更し、テスト用にモック/スタブをインジェクトすることができます。

リファクタリングする必要があるかどうかに答えるために、switchステートメント自体に問題はありません。ただし、それが1回だけ表示され、単純なままである限りです。パターンで修正できる重複やその他のコードの臭いに気づき始めた場合は、リファクタリングする必要があります。

于 2011-06-17T11:05:19.350 に答える
0

AbstractFactoryパターンのようなものを使用することを検討します。他の依存関係を作成する複雑なロジックをカプセル化できるため、IoCに関連して非常に便利です。次に、IoCツールを使用して抽象ファクトリを挿入し、switchステートメントを削除できます。

于 2011-06-17T11:01:23.813 に答える
0

私はおそらくこのようなものを使用します:

public interface IStatusHandler
{
    bool Handle(StatusData statusData);
}

public class Status1Handler : IStatusHandler
{
    public bool Handle(StatusData statusData)
    {
        if (statusData as Opt1Data == null) return false; // you don't need Type anymore

        ...

        return true;
    }
}

public class StatusManager
{
     private IList<IStatusHandler> handlers;

     public StatusManager(IList<IStatusHandler> handlers) // inject with IoC here
     {
         this.handlers = handlers;
     }

     public void ProcessStatus(StatusEventArgs args)
     {
         foreach(var handler in handlers)
             if (handler.Handle(args.Data)) return;

         throw new Exception("No handler for this kind of status!");
     }
}
于 2011-06-17T12:48:09.363 に答える