这种 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 语句更好方法。
有时我发现自己编写了一个如下所示的 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 语句更好方法。