2011-07-25 22 views
1

Mode(通常は列挙型で表現されます)をコマンドとその関係で実装から切り離すにはどうすればよいですか? モードスイッチ(int、enum、string、...)とそのコマンド呼び出しの間のゆるい束縛を記述する良いパターンですか?私はconfig経由でモードを追加したいので、これは(動的に)拡張が容易でなければなりません(プログラミングなしで)。私はすでにコマンドパターン(C#/ .NetのICommand)を知っています。それはコマンドのディクショナリとその関連モード番号である可能性がありますが、スイッチングロジックはどうですか?モード切り替えとコマンドを切り離す方法

答えて

2

のストラテジからコンテキスト(スイッチの切り替え、パラメータ)を切り離して、要求(入力)とその応答(出力)を解決することができます。

たとえば、 1つのコードベースでさまざまなケースでこの問題を解決します。 は、例えば、戦略は、入力と出力と評価する条件をその種類によって定義されます:コンテキストが異なる戦略を持っており、彼らの責任 ための戦略を尋ねる

public class Strategy<TInput, TOutput> 
{ 
    public Predicate<TInput> Condition { get; private set; } 
    public Func<TInput, TOutput> Result { get; private set; } 

    public Strategy(Predicate<TInput> condition, Func<TInput, TOutput> result) 
    { 
     Condition = condition; 
     Result = result; 
    } 

    public TOutput Evaluate(TInput input) 
    { 
     return Condition(input) ? Result(input) : default(TOutput); 
    } 
} 

(与えられた条件はOKです、結果を計算することができますリクエストの場合)。

public class Context<TInput, TOutput> 
{ 
    private List<Strategy<TInput, TOutput>> Strategies { get; set; } 

    public Context(params Strategy<TInput, TOutput>[] strategies) 
    { 
     Strategies = strategies.ToList(); 
    } 

    public TOutput Evaluate(TInput input) 
    { 
     var result = default(TOutput); 
     foreach (var strategy in Strategies) 
     { 
      result = strategy.Evaluate(input); 

      if (!Equals(result, default(TOutput))) 
       break; 
     } 

     return result; 
    } 
} 

のは、入力文字列が(スイッチケースのように)出力文字列 に解決する必要があり、簡単な例を見てみましょう。

1.(簡略化のためにこれは(あなたが見ることができるよう、すべてのメソッドは、独自のロジックとの懸念を持っている)あなたの行動を定義します。

private static string Move(string s) 
    { 
     if (s == "move") 
      return "doMove"; // here could be some more action... 
     return null; 
    } 

    private static string Query(string s) 
    { 
     if (s == "point") 
      return "queryPoint"; // here could be some more action... 
     return null; 
    } 

2.実行する条件を定義します。評価(のICommandのCanExecuteをリカ):

private static bool Condition(string s) 
    { 
     return !string.IsNullOrEmpty(s); // could eval different states, values 
    } 

...あなたも(例えば戦略につき一つの条件のeval関数を)以上の条件を定義することができ が、我々たちここでは1つしかありません。

var navigate = new Strategy<string, string>(Condition, Move); 
var query = new Strategy<string, string>(Condition, Query); 

2.コンテキストを(初期化スイッチを表します

3.戦略を作成し、コンテキスト(これらはスイッチの異なるパスを象徴し、彼らは私たちに結果を与える)ことにより、必要なオブジェクト入力付きボディ):コードに

var strategies = new List<Strategy<string, string>> {navigate, query}; 
var context = new Context<string, string>(strategies.ToArray()); 

3.ワイヤーそれら(例えばボタンclicクリックで「スイッチ」を実行k):

private void ButtonClick(object sender, RoutedEventArgs e) 
    { 
     var message = context.Evaluate(textBox1.Text); 

     if (message != null) MessageBox.Show(message); // display result 
    } 

...それです。

コンテキストはあなたに(右のアクションを行うか、あなたには、いくつかのアクション(例えばICommandの)を行う必要があり、「ツール」を与えることができます適切な戦略を提供します。

関連する問題