TDD 和代码度量中的 C# 嵌套 If 语句

本文关键字:嵌套 If 语句 代码 度量 TDD | 更新日期: 2023-09-27 18:30:31

public void AccessPermissions(User user)
{
   if (user.Age >= 18)
   {
      if (user.IsRegistred)
      {
         if (user.IsPowerfull)
         {
             AcessGrantLevel3();
         }
         else
         {
             AccessGrantLevel2();
         }
      }
      else
      {
         AccessGrantLevel1();
      }
   }
   else
   {
       AcceessDenied();
   }
}
根据代码度量测量,这个函数

非常糟糕,根据干净的代码开发,这个函数对测试不利。我该怎么做才能让代码度量和 TDD 满意?嵌套的 If 语句总是不好吗?

TDD 和代码度量中的 C# 嵌套 If 语句

public void AccessPermissions(User user)
{
    if(user.Age<18)
    {
        AccessDenied();
        return;
    }
    if(user.IsPowerfull && user.IsRegistered)
    {
        AccessGrantLevel3();
        return;
    }
    if(user.IsRegistered)
    {
        AccessGrantLevel2();
        return;
    }
    AccessGrantLevel1();
    return;
}

您可以像这样扁平化逻辑:

public void AccessPermissions(User user)
{
    if (user.Age < 18)
    {
        AcceessDenied();
    }
    else if (!user.IsRegistred)
    {
        AccessGrantLevel1();
    }
    else if (!user.IsPowerfull)
    {
        AcessGrantLevel2();
    }
    else
    {
        AccessGrantLevel3();
    }
}

它可以很容易地重写而无需嵌套。

public void AccessPermissions(User user)
{
   if (user.Age < 18)
   {
       AcceessDenied();
   }
   else if (!user.IsRegistred)
   {
       AccessGrantLevel1();
   }
   else if (user.IsPowerfull)
   {
       AcessGrantLevel3();
   }
   else
   {
       AccessGrantLevel2();
   }
}

这是一个偏好问题,但大多数人认为嵌套 if 语句的可读性较低且更难维护,因为要执行的代码与导致它的语句相去甚远。

通过反转 If 语句的条件,可以将执行逻辑移近该条件。 考虑:

public void AccessPermissions(User user)
{
    if (!(user.Age >= 18))
    {
        AcccessDenied();
    }
    else if (!user.IsRegistered)
    {
        AccessGrantLevel1();
    }
    else if (!user.IsPowerfull)
    {
        AccessGrantLevel2();
    }
    else
    {
        AccessGrantLevel3();
    }
}

最终,此页面上其他方法的多个示例中的任何一个例子都可以进行一些调整......这个概念仍然认为,你的目标应该是通过颠倒你的条件来减少或消除嵌套。

这是一种方法

public void AccessPermissions(User user)
{
    int UserLevel = 0;
UserLevel += (user.Age>=18) ? 1:0;      // Add 1 if user is over 18
UserLevel += (user.IsIsRegistred) ? 1:0;    // If registered, add another 1
UserLevel += (user.IsPowerFull) ? 1:0;      // Add another 1 if powerful
AccessGrantLevel( UserLevel );
}