具有多个返回点的重构方法

Odr*_*ade 11 c# refactoring

**编辑:下面有几个选项可行.请根据您对此事的看法进行投票/评论.

我正在使用以下基本结构清理和添加ac#方法的功能:

    public void processStuff()
    {
        Status returnStatus = Status.Success;
        try
        {
            bool step1succeeded = performStep1();
            if (!step1succeeded)
                return Status.Error;

            bool step2suceeded = performStep2();
            if (!step2suceeded)
                return Status.Warning;

            //.. More steps, some of which could change returnStatus..//

            bool step3succeeded = performStep3();
            if (!step3succeeded)
                return Status.Error;
        }
        catch (Exception ex)
        {
            log(ex);
            returnStatus = Status.Error;
        }
        finally
        {
            //some necessary cleanup
        }

        return returnStatus;
    }
Run Code Online (Sandbox Code Playgroud)

有许多步骤,并且在大多数情况下,步骤x必须成功才能进入步骤x + 1.现在,我需要添加一些总是在方法结束时运行的功能,但这取决于返回值.我正在寻找关于如何干净地重构这个以达到预期效果的建议.显而易见的选择是将依赖于返回值的功能放在调用代码中,但我无法修改调用者.

一种选择:

    public void processStuff()
    {
        Status returnStatus = Status.Success;
        try
        {
            bool step1succeeded = performStep1();
            if (!step1succeeded)
            {
                returnStatus =  Status.Error;
                throw new Exception("Error");
            }

            bool step2succeeded = performStep2();
            if (!step2succeeded)
            {
                returnStatus =  Status.Warning;
                throw new Exception("Warning");
            }

            //.. the rest of the steps ..//
        }
        catch (Exception ex)
        {
            log(ex);
        }
        finally
        {
            //some necessary cleanup
        }
        FinalProcessing(returnStatus);
        return returnStatus;
    }
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎有点难看.相反,我可以从performStepX()方法中直接抛出.但是,这会留下在processStuff()的catch块中适当设置returnStatus变量的问题.您可能已经注意到,处理步骤失败时返回的值取决于哪个步骤失败.

    public void processStuff()
    {
        Status returnStatus = Status.Success;
        try
        {
            bool step1succeeded = performStep1(); //throws on failure
            bool step2succeeded = performStep2(); //throws on failure

            //.. the rest of the steps ..//
        }
        catch (Exception ex)
        {
            log(ex);
            returnStatus = Status.Error;  //This is wrong if step 2 fails!
        }
        finally
        {
            //some necessary cleanup
        }
        FinalProcessing(returnStatus);
        return returnStatus;
    }
Run Code Online (Sandbox Code Playgroud)

我很感激您的任何建议.

bru*_*nde 9

不要使用异常来控制程序的流程.就个人而言,我会保留代码.要在最后添加新功能,您可以执行以下操作:

    public void processStuff()
    {
        Status returnStatus = Status.Success;
        try
        {
            if (!performStep1())
                returnStatus = Status.Error;
            else if (!performStep2())
                returnStatus = Status.Warning;

            //.. More steps, some of which could change returnStatus..//

            else if (!performStep3())
                returnStatus = Status.Error;
        }
        catch (Exception ex)
        {
            log(ex);
            returnStatus = Status.Error;
        }
        finally
        {
            //some necessary cleanup
        }

        // Do your FinalProcessing(returnStatus);

        return returnStatus;
    }
Run Code Online (Sandbox Code Playgroud)