哪种编码风格更好?

时间:2009-10-29 01:29:46

标签: coding-style nested

在代码审查期间,一位资深开发人员对我在代码中进行的一些嵌套进行了评论。他建议我设置一个bool值,这样我就不会有多个嵌套级别。我认为我的代码更具可读性,但希望得到其他开发者的意见。哪个风格更好?他的下意识是否厌恶筑巢?

以下是一些简化的代码示例。

嵌套:

If(condition1)
{
    If(condition2)
    {
        if(condition3)
        {
            return true;
        }
        else
        {
            log("condition3 failed");
        }
    else
    {
        log("condition2 failed")
    }
}
else
{
    log("condition1 failed")
}

return false;

Bool Driven:

bool bRC = false;

bRC = (condition1);
if(brc)
{
    bRC = (condition2);
}
else
{
    log("condition1 failed");
    return false;
}

if(bRC)
{
    bRC = (condition3);
}
else
{
    log("condition2 failed");
    return false;
}

if(bRC)
{
    return true;
}
else
{
    log("condition3 failed");
    return false;
}

14 个答案:

答案 0 :(得分:32)

我更喜欢你,但我可能会这样做:

if (condition1 && condition2 && condition3)
{
    return true;
}
else if (!condition1)
{
    log("condition1 failed");
}
else if (!condition2)
{
    log("condition2 failed");
}
else
{
    log("condition3 failed");
}
return false;

如果条件是复杂的表达式,那么我可以在评估if语句之前将表达式分配给适当命名的变量,以避免重新计算每个if中的值。

这假设正常模式是所有条件都为真,因此您希望首先进行检查。如果正常模式是一个或多个条件为假,那么我将重新排序并依次检查每个否定,如果所有检查都失败则返回true。这也将消除临时变量取代复杂表达式的需要。

答案 1 :(得分:19)

如果你对多个回归点没有任何愚蠢的规则,我认为这是非常好的(其他人也是如此,但是由于未知原因他们删除了答案):

if(!condition1)
{
    log("condition1 failed");
    return false;
}

if(!condition2)
{
    log("condition2 failed");
    return false;
}

if(!condition3)
{
    log("condition3 failed");
    return false;
}

return true;

也许这对于超级嵌套是一种相同的下意识的厌恶,但它肯定比他在某些值中存储布尔条件的垃圾更清晰。但是,它在上下文中可能不太可读:考虑其中一个条件是isreadable()。说if(isreadable())更清楚,因为我们想知道某些东西是否可读。 if(!isreadable())建议我们是否想知道它是否不可读,这不是我们的意图。当然有可能存在一个比另一个更可读/更直观的情况,但我自己也是这种方式的粉丝。如果有人挂断了回报,你可以这样做:

if(!condition1)
    log("condition1 failed");

else if(!condition2)
    log("condition2 failed");

else if(!condition3)
    log("condition3 failed");

else
    return true;

return false;

但在我看来,这是相当卑鄙的,并且不那么“明确”。

答案 2 :(得分:18)

我个人觉得嵌套代码更容易阅读。

答案 3 :(得分:6)

我通常更喜欢为我的条件嵌套;当然,如果我的嵌套条件越来越向右缩进,我不得不开始想知道是否有更好的方法去做我正在尝试做的事情(重构,重新设计等等)。

答案 4 :(得分:5)

与嵌套版本类似,但对我来说更清洁:

if not condition1:
    log("condition 1 failed")
else if not condition2:
    log("condition 2 failed")
else if not condition3:
    log("condition 3 failed")
else
    return true;
return false;

请注意每种情况都要评估一次。

答案 5 :(得分:3)

第二种风格是荒谬冗长的:他是否真的建议这一点?您不需要大多数if语句,因为else部分中有return

使用嵌套示例,您依赖于不要忘记包含任何可能的else子句。

这些似乎都不令我满意。

答案 6 :(得分:2)

布尔驱动的方式令人困惑。如果需要,嵌套很好,但是你可以通过将条件组合到一个语句中来删除一些嵌套深度,或者调用一些进一步评估的方法。

答案 7 :(得分:2)

我认为这两种方式都是可能的,并且有其优点和缺点。我会使用bool驱动的样式,我会有非常深的嵌套(8或10或类似的东西)。在你的3个级别的情况下,我会选择你的风格,但对于上面的确切样本,我会这样:

void YourMethod(...)
{
  if (condition1 && condition2 && consition3)
    return true;

  if (!condition 1)
    log("condition 1 failed");

  if (!condition 2)
    log("condition 2 failed");

  if (!condition 3)
    log("condition 3 failed");

  return result;
}

...或者如果您喜欢单个退出点(就像我那样)......

void YourMethod(...)
{
  bool result = false;

  if (condition1 && condition2 && consition3)
  { 
    result = true;
  }
  else
  {
    if (!condition 1)
      log("condition 1 failed");

    if (!condition 2)
      log("condition 2 failed");

    if (!condition 3)
      log("condition 3 failed");
  }
  return result;
}

这样,您将获得第一次运行中记录的所有失败条件。在您的示例中,即使存在多个失败条件,也只会记录一个失败的条件。

答案 8 :(得分:1)

我可能会选择

   if (!condition1)      log("condition 1 failed");
   else if (!condition2) log("condition 2 failed");
   else if (!condition3) log("condition 3 failed");
   // -------------------------------------------
   return condition1 && condition2 && condition3;

我相信这是等同的,更清洁......

此外,一旦客户决定所有条件都应该被评估并记录,如果它们失败,而不仅仅是第一个失败,那么修改它就容易得多:

   if (!condition1) log("condition 1 failed");
   if (!condition2) log("condition 2 failed");
   if (!condition3) log("condition 3 failed");
   // -------------------------------------------
   return condition1 && condition2 && condition3;

答案 9 :(得分:1)

如果语言支持异常处理,我将使用以下内容:

try {
    if (!condition1) {
        throw "condition1 failed";
    }

    if (!condition2) {
        throw "condition2 failed";
    }

    if (!condition3) {
        throw "condition3 failed";
    }

    return true;

} catch (e) {
    log(e);
    return false;
}

编辑来自charles bretana:请参阅Using Exceptions for control flow

答案 10 :(得分:1)

这是我实现它的方式,只要您的实现实际上反映了所需的行为。

if (!condition1) {
    log("condition1 failed");
    return false;
}
if (!condition2) {
    log("condition2 failed");
    return false;
}
if (!condition3) {
    log("condition3 failed");
    return false;
}
return true;

但是,我认为应该记录每个失败的情况。

result = true;
if (!condition1) {
    log("condition1 failed");
    result = false;
}
if (!condition2) {
    log("condition2 failed");
    result = false;
}
if (!condition3) {
    log("condition3 failed");
    result = false;
}
return result;

答案 11 :(得分:1)

我不喜欢这两种方式。如果你有这么多巢,那就错了。在表单验证或确实需要这样的东西的情况下,尝试找出更模块化或更紧凑的东西。

一个例子是一个包含条件的数组,你可以通过它来迭代一段时间,并根据需要打印/中断。

根据您的需求实现太多,因此创建示例代码毫无意义。

根据经验,当你的代码看起来太复杂时,它很糟糕:)。尝试重新思考它。大多数时候遵循编码习惯会使代码变得更加审美和简短;显然,也更聪明。

答案 12 :(得分:0)

代码应以给定的语言重述问题。因此,我认为任何一个片段都可以“更好”。这取决于被建模的问题。虽然我的猜测是这两种解决方案都不会与实际问题相提并论。如果您使用实际术语而不是条件1,2,3,它可能会完全改变“最佳”代码 我怀疑有更好的(3d)方法可以将它们全部写在一起。

答案 13 :(得分:0)

if( condition1 && condition2 && condition3 )
    return true;

log(String.Format("{0} failed", !condition1 ? "condition1" : (!condition2 ? "condition2" : "condition3")));
return false;

这样,您不必为了记录而看到许多代码行。如果您的所有条件都是真的,那么您不必浪费时间来评估它们,以防您需要记录。