JavaScript is required
Blog About

【译】如何简化布尔表达式

2024/06/11
3 mins read
See this issue
# Javascript
# 代码规范
Back

您可能在代码库中遇到了一些复杂的、难以阅读的布尔表达式,并希望它们更容易理解。例如,假设我们想决定披萨是否很棒:

if ((!pepperoniService.empty() || sausages.size() > 0)
    && (useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO)) && hasCheese()) {
  ...
}

改进这一点的第一步是将条件提取到一个名称良好的变量中:

boolean isPizzaFantastic = 
    (!pepperoniService.empty() || sausages.size() > 0)
    && (useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO)) && hasCheese();

if (isPizzaFantastic) {
  ... 
}

但是,布尔表达式仍然太复杂。从一组给定的输入中计算isPizzaFantastic的值可能会令人困惑。您可能需要拿起笔和纸,或者在本地启动服务器并设置断点。

相反,尝试将细节分组到提供有意义抽象的中间布尔值中。下面的每个布尔值代表一个定义明确的质量,您不再需要在表达式中混合&&||。在不更改业务逻辑的情况下,您可以更轻松地查看布尔值之间的关系:

boolean hasGoodMeat = !pepperoniService.empty() || sausages.size() > 0;
boolean hasGoodVeggies = useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO);
boolean isPizzaFantastic = hasGoodMeat && hasGoodVeggies && hasCheese();

另一种选择是在单独的方法中隐藏逻辑。这也提供了使用保护子句提前返回的可能性,进一步减少了跟踪中间状态的需要:

boolean isPizzaFantastic() {
  if (!hasCheese()) {
    return false;
  }

  if (pepperoniService.empty() && sausages.size() == 0) {
    return false;
  }

  return useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO);
}