【问题标题】:Throwing exception instead to deal with returns抛出异常来处理返回
【发布时间】:2019-01-10 06:18:14
【问题描述】:

我正在尝试重构一英里长的方法,并且正在考虑是否抛出 ReturnException 而不是调用 return。看我的例子:

当前一英里长的代码如下所示:

  public void MyMileLongMethod()
  {
        //some logic
        //some more logic

        if (a == 10 && (b == "cool" || b == "super cool"))
        {
            //logic here 
            //more logic
            //15 more lines of code. 
            return;
        }

        if (x && y || z==5)
        {
            //logic here 
            //more logic
            //20 more lines of code. 
            return;
        }
        //more conditions like this that calls a return
        // probable more logic here
    }

我想用以下方式重构它:

    public void MyRefactoredMethod()
    {
        try
        {
            DoLogic1(parameters);

            ConditionOneMethod(parameters);

            ConditionTwoMethod(parameters);

            //more methods like above that throws a ReturnException
            // probable more logic here
        }
        catch (ReturnException)
        {
            return;
        }
    }
    void DoLogic1(parameters)
    {
        //some logic
        //some more logic
    }

    void ConditionOneMethod(parameters)
    {
        if (a == 10 && (b == "cool" || b == "super cool"))
        {
            //logic here 
            //more logic
            //15 more lines of code. 
            throw new ReturnException();
        }
    }

    void ConditionTwoMethod(parameters)
    {
        if (x && y || z == 5)
        {
            //logic here 
            //more logic
            //20 more lines of code. 
            throw new ReturnException();
        }
    }

问题:抛出异常并在调用的方法中捕获它,然后在 catch 中调用 return 是一种好习惯吗?如果,那么有一个常用的模式名称吗? 如果这不是一个好习惯,还有其他方法吗?还是我下面的解决方案就是答案?

我的另一个解决方案是,检查外部方法中的条件,然后调用执行逻辑的方法,然后调用 return,但在我看来,外部方法中有很多代码。

【问题讨论】:

  • 在我看来,这是对异常/处理系统的滥用。
  • 你应该使用锤子来做它的用途 - 不要试图用它刷牙/仅在特殊处理时使用例外
  • @SirRufo 我喜欢你解释它的方式))。
  • 你应该看看Chain of Responsibility设计模式
  • 使用异常来控制流是一件坏事

标签: c# design-patterns return refactoring


【解决方案1】:

我赞成使用这种变体:

private void MyRefactoredMethod(...) {
    ...
    if (...)
        return; // was "continue;"
    ...
    if (!ConditionOneMethod(...))
        return;
    ...
}

private boolean ConditionOneMethod(...) {
    ...
    if (...)
        return false; // was a continue from a nested operation
    ...
    return true;
}

【讨论】:

  • 如果 OP 不喜欢明确的 return 调用,他们也可以使用 var allExecuted = DoLogic1() && ConditionOneMethod() && 等。这很丑陋,但比使用异常要好。
猜你喜欢
  • 2013-07-24
  • 1970-01-01
  • 2018-07-27
  • 2011-10-10
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 2012-12-22
相关资源
最近更新 更多