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

策略模式通过将每个分支中的大段代码重构为单独的类(或方法)来提供帮助。然后,您的 switch 就变成了选择适当策略类(或方法委托)的简单情况,然后在 switch 语句的末尾通过一次调用执行。因此大致是这样的:

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

变成这样:

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

您需要将逻辑重构为一系列实现公共接口(或扩展公共基类)的类,或一系列具有兼容签名的方法,以便您的策略可以选择匹配的委托。正如 Oded 在他的评论中暗示的那样,您不一定会摆脱select这样做,但每个案例都会变得更小。

从您的简短描述来看,这听起来确实是使您的代码更简单、更易于维护的适当方法。

于 2012-05-18T09:23:08.010 回答