日期:2014-05-20  浏览次数:20956 次

[提问]如何对一个长达300行的函数做重构
函数例子,实际的长度有300多行,其中200多行是对参数以及各种运行状态做判断。
如果方法成功,返回0,否则返回各种错误状态。
C# code

        List<int> GetErrorParamTypes()
        {
            return new List<int>();
        }

        public int LongFun(int param1, int param2, int param3)
        {
            // 参数验证
            if (param1 == 0 || param2 == 0 || param3 == 0)
                return -1;

            if (param1 == param2)
                return -2;

            foreach (var errorType in GetErrorParamTypes())
            {
                if (errorType == param1)
                    return -3;
            }

            if (param3 == 10)
                return -4;

            // 做一些数据操作
            return 0;
        }



目前根据验证的内容,做了一些分类,分成几个不同的验证函数,但是现在存在的一个问题是,每次调用验证函数,都需要判断一个返回值,如果验证成功则继续,否则返回验证函数返回的错误值。
现在就是在主函数里还需要多验证一次错误值这个地方感觉有点不漂亮,想问一下大家有没有什么好的代码模式可以参考。

C# code

        public int LongFun2(int param1, int param2, int param3)
        {
            // 参数验证
            if (param1 == 0 || param2 == 0 || param3 == 0)
                return -1;

            var ret = verify1(param1, param2);
            if (ret != 0)    // 验证是否成功
                return ret;

            ret = verify2(param3);
            if (ret != 0)
                return ret;

            // 做一些数据操作
            return 0;
        }

        /// <summary>
        /// 验证分类1
        /// </summary>
        int verify1(int param1, int param2)
        {

            if (param1 == param2)
                return -2;

            foreach (var errorType in GetErrorParamTypes())
            {
                if (errorType == param1)
                    return -3;
            }
            return 0;
        }

        /// <summary>
        /// 验证分类2
        /// </summary>
        int verify2(int param3)
        {
            if (param3 == 10)
                return -4;
            return 0;
        }



------解决方案--------------------
改成返回void,如果不对就抛EXCEPTION,把相应的错误吗放在EXCEPTION.是不是减少点代码。
------解决方案--------------------
哦,也许重写也可以说是一种重构。我还是解释一下吧,免得误会。

我说重写,是指你应该针对简单的例子来重写逻辑。然后当例子由1个增加到2、3、4个,随着增加,这时候要做的是面向接口进行设计,而不是堆砌switch判断分支。

因此,你的问题是出在软件面向对象设计的基础理论上,仅学点简单的编程技巧已经无法解决你的问题了。
------解决方案--------------------
重写。foreach 可以用 arraylist.contains 代替
------解决方案--------------------
mark.
------解决方案--------------------
gof说过,代码过长就有坏味道。sp1234的意见是很中肯的。可以考虑用面向对象的设计思想
------解决方案--------------------
估计 lz 看过 Refactoring 了,建议再看看 Clean Code!

Clean Code 是一项技能,需要不断实践和摸索!

1 理清逻辑;
2 消除重复代码,封装 small 方法,给每个 method 起一个见名知意的名字;
3 重复 1-2 的步骤!

至于 lz 所说的返回错误代码的问题,在 Clean Code 中也提到了,
建议是改为 throw Exception 的方式,不过这样对于结构的改动就比较大了,需要谨慎应用!

另,一些问题不在于代码实现,而在于最初的代码设计,比如错误代码和与异常的选择等等,
Refactoring 和 Clean Code 都需要以 Test 为基础,否则就非常危险了!!!
------解决方案--------------------
请楼主仔细研读吴伟同志在3、4楼的答复,还有高翌翔同志在14楼的答复,

如果您还不能理解,那重写这些代码对您来说有些勉为其难了