0

オペランド/演算子をパラメータとし、評価結果を提供する関数が必要です。 私が直面している問題は、オペレータをエレガントに解析する方法です。マッチオペレータとリファクタリングスイッチケースの解析

サンプルコードは、私がスイッチケースを除去するために、列挙(又は伸縮列挙)と使用戦略パターンでの演算子を置くことができる

internal static bool Evaluator(double operand1, double operand2, string operation) 
{ 
    bool evaluation = false; 
    switch (operation) 
    { 
     case "<": 
      evaluation = operand1 < operand2; 
      break; 

     case ">": 
      evaluation = operand1 > operand2; 
      break; 

     case "<=": 
      evaluation = operand1 <= operand2; 
      break; 

     default: 
      break; 
    } 

    return evaluation; 
} 

以下の通りです。 問題が残っています。演算子を解析できません。 例

 op1="<"; 
    var operation = Operation.Parse(op1); 
    var result = operand1 <-- operation should come here --> operand2. 

エレガントなコードの上(評価者機能)をリファクタリングする方法を提案してください。

答えて

1

その目的は、問題を正しいハンドラにルーティングすることです。従来のGoF実装はLinked Listです。 Wikipediaには、良い記事があります(NetObjectives)。

問題のもう一つの良い実装はレジストリの実装です。これは、ルールが常に同じであるため、ここで機能します。指定されたキーを操作に一致させます。この抽象化を記入し、辞書でそれを支持する。あなたが知っている操作で辞書をあらかじめロードしてください。

public abstract class OperationRegistry 
{ 
    public abstract void RegisterOperation(string symbol, Func<double, double, bool> operation); 
    public abstract Func<double, double, bool> GetOperation(string symbol); 
} 

FWIW、私はFuncの代わりに新しいクラスを見たいと思いますが、おそらくそれは私だけです。

+0

独占的な実装は私にとってはきれいだ。 Funcに関して、あなたは正しいです、新しいクラスはより良いです。 – Tilak

1

私はあなたがこのような何かを探しているかもしれないと思う:

public static Func<double, double, bool> ParseOperation(string operation) 
{ 
    switch (operation) 
    { 
     case "<": 
      return (x, y) => x < y; 

     case ">": 
      return (x, y) => x > y; 

     case "<=": 
      return (x, y) => x <= y; 

     default: 
      throw new Exception(); 
    } 
} 

あなたはこのようにそれを使用することができます:switch文は、Chain of Responsibilityパターンの最も単純な実装である、

var op = ParseOperation("<"); 
Console.WriteLine(op(1, 2)); // true 
+0

非常に近く、きちんとしています。私は同様のものを探していますが、後でさらにいくつかの演算子を追加するためにswitch-caseを削除したいと思います。 – Tilak