哪种语法更适合返回值?

时间:2020-03-06 14:47:10  来源:igfitidea点击:

我一直在进行大量的代码审查,而我在各处注意到的一种模式是:

public bool MethodName()
{
    bool returnValue = false;
    if (expression)
    {
        // do something
        returnValue = MethodCall();
    }
    else
    {
        // do something else
        returnValue = Expression;
    }

    return returnValue;
}

这不是我应该做的那样,当我知道它的值时,我将只返回该值。这两种模式中的哪一种更正确?

我强调,逻辑似乎总是结构化的,使得返回值只能一次分配,并且分配后不执行任何代码。

解决方案

我本来会用三元来减少控制结构的。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

return expression ? MethodCall() : Expression;

这里有一个关于此主题的冗长讨论。

他们俩都完成相同的任务。有人说一种方法应该只有一个入口和一个出口点。

一些学习机构和书籍提倡单归实践。

更好与否是主观的。

我也用这个。这个想法是可以在程序的正常流程中释放资源。如果我们跳出20个不同位置的方法,并且需要先调用cleanUp(),则必须再添加20次清理方法(或者重构所有内容)

我怀疑自己会占少数,但我喜欢示例中显示的样式。添加日志语句并设置断点IMO很容易。另外,以一致的方式使用时,"模式匹配"似乎比获得多个收益更容易。

但是,我不确定对此是否有"正确"的答案。

我猜想编码人员已经设计了在方法顶部定义对象toReturn的设计(例如,List <Foo> toReturn = new ArrayList <Foo>();),然后在方法调用期间填充它,并以某种方式决定了将其应用于布尔返回类型,这很奇怪。

也可能是编码标准的副作用,该标准指出我们不能在方法主体的中间(只能在最后)返回。

即使现在分配了返回值后也没有执行任何代码,这并不意味着以后不必添加某些代码。

它不是可以使用的最小代码,但是对重构非常友好。

许多人建议方法中只有一个出口点。我们上面描述的模式遵循该建议。

该建议的主要要点是,如果我们必须在从方法返回之前清理一些内存或者状态,最好只将该代码放在一个位置。具有多个出口点会导致清除代码重复或者由于在一个或者多个出口点缺少清除代码而导致潜在的问题。

当然,如果方法只有几行或者不需要任何清理,则可能会有多个返回。

这看起来像是糟糕的OOP设计的一部分。也许应该在比单个方法内部更高的级别上对其进行重构。

否则,我更喜欢使用三元运算符,如下所示:

return expression ? MethodCall() : Expression;

它更短,更易读。

Delphi通过自动创建一个名为" Result"的变量来强制这种模式,该变量将是函数的返回类型。函数退出时,无论"结果"是什么,都是返回值。因此根本没有" return"关键字。

function MethodName : boolean;
begin
  Result := False;
  if Expression then begin
    //do something
    Result := MethodCall;
  end
  else begin
    //do something else
    Result := Expression;
  end;

  //possibly more code
end;

使用的模式是冗长的,但是如果我们想知道返回值而无需打开"寄存器"窗口并检查EAX,则它也更容易调试。

在以下任何一种情况下,立即从方法返回:

  • 我们已经找到边界条件,需要返回一个唯一值或者标记值:if(node.next = null)返回NO_VALUE_FOUND;
  • 所需的值/状态为false,因此该方法的其余部分不适用(也称为保护子句)。例如:if(listeners == null)返回null;
  • 该方法的目的是查找并返回特定值,例如:if(nodes [i] .value == searchValue)return i;
  • 我们在一个子句中,该子句从方法中未使用的方法中返回唯一值:`if(userNameFromDb.equals(SUPER_USER))return getSuperUserAccount();。

否则,只有一个return语句会很有用,这样可以更轻松地添加调试日志记录,资源清理和遵循逻辑。我尝试先处理上述4种情况(如果适用),然后尽可能晚地声明一个名为result(s)的变量,并根据需要为其分配值。