如何处理无效的执行状态?

时间:2009-04-15 07:41:56

标签: branch if-statement

假设您有以下代码块:

if (Light.On) {
    // do something...
} else if (Light.Off) {
    // do something else...
} else {
    // this state should never be reached
}

现在假设应用程序逻辑规定在代码的这一部分中,永远不应该达到最后一个状态,但它不能在编译时确定。也许还有其他状态(例如Light.Broken)可以由应用程序的其他部分设置,但这里没有使用。

您在上一个else区块中添加了哪些代码?

  1. 不添加任何代码,因为无论如何都不应该访问它。
  2. 添加一些日志记录功能,以便您作为开发人员知道已达到某种非法状态。
  3. 抛出异常,因为一定不能到达状态,无论如何都达到了,其他一些东西一定是错的。
  4. 第一种选择对我来说似乎不合理,希望正确的事情似乎不是正确的选择。选项二的优势在于您的应用程序不会立即崩溃,因此如果在极少数情况下发生这种情况而未在测试中发现,则客户可以继续使用该应用程序,并通知开发人员该问题。选项三导致应用程序崩溃,这显然不是您希望客户体验的东西,但它确实表明出现问题。

    处理这种情况的最佳方法是什么?

    根据评论编辑:

    引导讨论的一些额外考虑因素:

    • 包含上述代码的方法的合同不允许在此时设置任何其他值,然后打开和关闭。
    • 假设代码位于应用程序的一个不太关键的部分。

7 个答案:

答案 0 :(得分:6)

在开发中 - 努力失败并快速失败。抛出某种运行时异常,或者只是Assert(false)。

在发布中 - 优雅地关闭。您的应用程序处于无法使用的状态,您无法依赖通常会发生的任何事情,例如类不变量等。让用户有机会保存他们的工作,例如,尝试并记录可能会发送回给他们的错误。开发团队然后关闭。

编辑:根据添加的评论。

如果函数的契约声明在函数入口处打开或关闭灯光,那么任何其他状态都是错误的。根据我原来的答案中概述的原则,该功能应该失败。

关于'非关键'aspaect - 如果未满足函数前提条件,则表示您的应用程序已损坏。无论在非关键代码段中检测到错误,这并不意味着问题本身并不重要 - 您无法知道创建无效状态的错误也不会影响代码的关键区域

答案 1 :(得分:2)

嗯......这取决于。有一个布尔测试的第三种情况会让我想哭。这只是噪音,增加了混乱,告诉我开发人员至少和我的感觉一样困惑。

对于非布尔值,我猜你可以做任何事......如果if s捕获与相关代码相关的状态,那么忽略其他情况就没有坏处。如果将来很有可能需要进一步的案例,那么评论可能足以表明清楚。

答案 2 :(得分:1)

如前所述,在开发阶段,您应该尽快将其显示出来。在发布阶段,它取决于达到此无效状态的重要程度。

最少发布日志以进行调试。

然后,您可以尝试通过返回先前的有效状态或进入新的有效状态来从此无效状态恢复。

最后,如果无法安全,您可以终止执行(向用户发出警报并向维护者发送日志)。

答案 3 :(得分:0)

第3个选项是正确的,就好像该部分任何其他状态无效所以它应该抛出和异常说无效状态。

答案 4 :(得分:0)

不要做任何事情。如果您关心的是灯是否亮起:

if (Light.On) {
    // do some work
} else {
    // too darned dark to work
}

否则你应该列举你所有的州。

如果不允许其他状态,则应该出错。如果他们被允许但不相关,那就忽略它们。使用设计合理的代码,没有问题。

这里的主要问题在于可以同时设置Light.On和Light.Off的设计。你应该使用一个Light.State状态,它被设置为{on,flickering,off,broken,unplugged,explosion,emit_dangerous_gamma_rays}之一等等。

答案 5 :(得分:0)

抛出异常。

如你所说,第三种情况不应该发生。如果它确实发生了,那么出现了问题,你不知道还有什么可能出错。

您也不希望调用代码时认为代码在实际失败时正常工作。

此外,它可以更容易地发现问题在发布之前。

答案 6 :(得分:0)

在开发版中,只是抛出异常。

在发布版本中:

  • 抛出异常
  • 如果可能,将用户的工作保存在某个临时文件中
  • 保存故障转储和(使用小帮助应用程序)为用户提供发送给您的选项,以便您可以识别并解决问题