这种 bool 方法是一种不好的做法吗?

Is this kind of a bool method a bad practice?

有时我发现自己编写了一个如下所示的 bool 方法:

public bool isRunning()
    {
        if (!(move == Moving.None) && staminaRegan == true)
        {
            if (keyState.IsKeyDown(Keys.Space))
            {
                EntityAnimation.interval = 10;
                return true;
            }
            else
            {
                EntityAnimation.interval = 65;
                return false;
            }
        }
        else 
        {
            EntityAnimation.interval = 65;
            return false;
        }
    }

(顺便说一句,这是 XNA)如您所见,我有一个 bool isRunning,我在其中做了一个 if 语句,我在其中检查 if (Player is moving) && (regains stamina, which is set to false once耐力值小于 6.0f) 然后我简单地检查 Space 是否被按下,如果是那么我的动画速度更快(间隔越小,spritesheet 变化越快),然后它发送真值,这意味着 Player 是 运行, 否则我不会因为 Space 没有被按下。

然后我必须在第一个 if 语句之外重复此 'else' 代码,以便它发送 Player is not 运行 如果 Player 没有移动或他的耐力 Regan 为假;

所以我只是想知道这种 bool 方法是否被认为是一种不好的做法(你在嵌套 if 中重新运行 true 和 false 值,然后在嵌套 if 之外返回 return false 并重复相同的代码) ?

我喜欢这种风格,我也用它。首先,您可以更轻松地阅读代码,其次它具有调试优势,因为您可以为个别 else 情况设置断点。否则你需要使用断点条件。

在一个方法中使用一个 return 语句是一种很好的做法。有人对此争论不休,但这是一种观点。

通过删除不必要的代码使 if 语句清晰也是一个好习惯:

public bool isRunning()
{
    bool result = false;
    if (move != Moving.None && staminaRegan)
    {
        if (keyState.IsKeyDown(Keys.Space))
        {
            EntityAnimation.interval = 10;
            result = true;
        }
        else
        {
            EntityAnimation.interval = 65;
        }
    }
    else
    {
        EntityAnimation.interval = 65;
    }

    return result;
}

您可以重写代码如下;那么代码不会重复:

public bool isRunning()
{
    if (move != Moving.None && staminaRegan && keyState.IsKeyDown(Keys.Space))
    {
        EntityAnimation.interval = 10;
        return true;
    }
    else
    {
        EntityAnimation.interval = 65;
        return false;
    }
}

或者如果你不想要多余的 else:

public bool isRunning()
{
    if (move != Moving.None && staminaRegan && keyState.IsKeyDown(Keys.Space))
    {
        EntityAnimation.interval = 10;
        return true;
    }

    EntityAnimation.interval = 65;
    return false;
}

我会考虑在自文档中引入一个命名布尔值,我会将 staminaRegan 重命名为 staminaIsRegenerating

public bool isRunning()
{
    bool isMovingQuickly = (move != Moving.None) && staminaIsRegenerating && keyState.IsKeyDown(Keys.Space);

    if (isMovingQuickly)
        EntityAnimation.interval = 10;
    else
        EntityAnimation.interval = 65;

    return isMovingQuickly;
}

不过,最重要的是,您应该重命名该方法以更准确地描述它在做什么:

public bool CheckIfRunningAndSetAnimationInterval()

该方法有副作用,这就是为什么它是不好的做法

 public bool isRunning()

在查看方法的签名时,我们期望只有 true/false 答案,仅此而已。然而,方法改变实例的状态:

  ...
  if (!(move == Moving.None) && staminaRegan == true)
    {
        if (keyState.IsKeyDown(Keys.Space))
        {
            EntityAnimation.interval = 10; // <- Aaa! The interval is changed 
            return true;
        }
  ...

我建议将初始方法拆分为一个属性和一个方法

 // No side effect: just answer is running or not
 public bool IsRunning {
   get {
     return (move != Moving.None) && staminaRegan && KeyState.IsKeyDown(Keys.Space);
   }
 }

 // Put the right interval based on instance internal state 
 // (if it's running etc.)
 public void AdjustInterval() {
   if (IsRunning) // and may be other conditions
     EntityAnimation.interval = 10; //TODO: move magic number into constant 
   else 
     EntityAnimation.interval = 65; //TODO: move magic number into constant
 } 

我认为我们为人(其他开发人员)编写代码,当然机器执行代码,但开发人员 80% 的工作都在阅读代码。
基于此,我认为阅读流程必须与执行代码的流程完全相同——这就是为什么我认为乘法 return 语句不是一件坏事,甚至比你的底部只有一个 return 语句更好方法。