3

我继承了一些代码,其中有一个 500 行的 switch 语句。基本上,它打开一个string任务并执行相应的动作。

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

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

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

我正在考虑使用将sDictionary映射stringActions 来消除整个开关,但这不起作用,因为我使用了很多 ref 参数(原始类型)并且无法将它们传递给构造函数,并让它们稍后被引用修改。

该问题的明显解决方案是将所有 16 个左右的变量放入一个单独的类中并传递它,但其中很多不是很相关,所以它只是用另一个问题替换一个问题(带有非内聚数据的长参数列表班级)。

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

4

3 回答 3

3

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

于 2012-10-17T03:32:13.047 回答
3

由于您的问题不包含代码,因此答案也不能。我认为最好的做法是向您指出有史以来最好的软件书籍之一的第 82 页:重构:改进现有代码的设计

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

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

于 2012-10-17T03:46:33.310 回答
1

您可以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;
    }              

}

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

于 2012-10-17T03:36:05.560 回答