解析匹配运算符和重构切换案例

时间:2012-04-29 03:35:52

标签: .net design-patterns refactoring switch-statement strategy-pattern

我需要一个将操作数/运算符作为参数并提供评估结果的函数。 我面临的问题是如何优雅地解析操作符。

示例代码如下

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;
}

我可以将运算符放在枚举(或可扩展的枚举)中,并使用策略模式来删除switch case。 问题仍然存在,我无法解析运营商。 示例

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

请建议如何优雅地重构上面的代码(Evaluator功能)。

2 个答案:

答案 0 :(得分: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();
    }
}

你可以像这样使用它:

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

答案 1 :(得分:1)

switch语句是责任链模式的最简单实现,其目的是将问题路由到正确的处理程序。经典的GoF实现是链接列表。 Wikipedia有一篇好文章,NetObjectives也是如此。

另一个很好的实现问题是Registry实现。这可以在这里工作,因为规则总是相同的 - 将给定的键与操作匹配。填写这个抽象,用字典支持它。使用您了解的操作预加载字典。

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,但也许这只是我。