如何重构这个巨大的switch语句?

时间:2012-10-17 03:08:18

标签: c# refactoring switch-statement

我继承了一些代码,其中包含500行开关语句。基本上,它会打开string任务并执行相应的操作。

我已经将每个case语句移动到一个新类中的自己的方法中。巨大的switch语句仍然存在,但不是内联逻辑,而是每个案例只调用一个方法,所以它更整洁。

问题是这些方法修改了很多不同的东西。 50%的方法需要传入0个参数。大约40%需要5个参数,剩下的10%需要10个参数。

目前这个有效,但我想让它变得更好。要么以某种方式摆脱switch语句或降低传入参数的数量。

我正在考虑使用Dictionarystring映射到Action来消除整个切换,但这不起作用,因为我使用了很多参考参数(原始类型)并没有办法将它们传递给构造函数,并在以后对它们进行引用修改。

该问题的显而易见的解决办法就是将所有16个左右的变量放入一个单独的类中并传递它,但是很多它们并不是很相关所以它只是将一个问题替换为另一个问题(长参数列表与非 - 粘性数据类)。

想知道是否有其他方法可以改进此代码。谢谢你的阅读。

3 个答案:

答案 0 :(得分:3)

如果不能查看任何类型的代码,我可以给出的唯一建议是,您应该考虑使用SOLID design principles进行重构并进行测试。我会尝试为每个逻辑模块(或交换机的条件)创建不同的类,通过这些对象的构造函数(而不是方法的参数)传递依赖关系,并尝试创建一些可用于工作的统一接口在一些测试中。您可能希望通过投入工厂来提取这些对象的条件创建。听起来像是一团糟。祝你好运。

答案 1 :(得分:2)

由于您的问题不包含任何代码,因此答案也不是。我认为最好的办法是为您指出其中一本有史以来最好的软件书籍的第82页:Refactoring: Improving the Design of Existing Code

“面向对象代码最明显的症状之一是它缺乏switch语句。大多数时候你会看到一个switch语句,你应该考虑多态性。”

然后,他列出了一些用于帮助实现这一目标的具体模式。

答案 2 :(得分:0)

您可以在代理中使用ref参数,但不能使用内置的ActionFunc通用代理。你必须像这样定义自己的:

public delegate void DelegateWithRefParameters(ref int i, ref long l, ref bool b, ref object o);

public class Program
{
    public static void Main(string[] args)
    {
        int i = 0;
        long l = 0;
        bool b = false;
        object o = null;

        var lookup = new Dictionary<string, DelegateWithRefParameters>() 
        {
            { "object", ModifyObject },
            { "int", ModifyInt },
            { "bool", ModifyBool },
        };

        string s = "object";

        lookup[s](ref i, ref l, ref b, ref o);
    }

    private static void ModifyObject(ref int i, ref long l, ref bool b, ref object o)
    {
        o = new object();
    }

    private static void ModifyInt(ref int i, ref long l, ref bool b, ref object o)
    {
        i++;
    }

    private static void ModifyBool(ref int i, ref long l, ref bool b, ref object o)
    {
        b = !b;
    }              

}

您只需修改所有方法即可使用相同的签名。