为什么快速失败风格的程序比防御风格的程序更短?

7

我读过有关像Erlang这样的语言中快速失败编程风格的文章,发现它们的程序比大多数其他语言中的防御式编程风格的程序要短得多。那么所有类型的程序都是如此吗?这样做的理由是什么?


2
我打算打破传统,问一下为什么要将这个设为社区维基。 :) - JUST MY correct OPINION
我应该将其更改为非社区维基吗?我从来不确定哪些是社区维基,哪些不是。 - yazzapps.com
社区 wiki 的重要之处在于人们可以编辑任何回复以修正错误,而且没有为提交回复的用户给予点赞积分。而普通模式则会给予点赞积分,并且只有拥有最低积分的用户才能编辑回复。 - I GIVE TERRIBLE ADVICE
为了获得答案,最好不要将问题设为社区维基页面。 - yazzapps.com
3个回答

10

Fail-fast程序不一定比防御性编程风格的程序更短:这取决于实现和需要采取的措施来确保你的防御性代码的安全性。

对于Erlang,在声明式风格和虚拟机如何确保为您生成错误情况的情况下,故障快速的程序通常较短。例如在以下函数中:

day(1) -> sunday;
day(2) -> monday;
day(3) -> tuesday;
day(4) -> wednesday;
day(5) -> thursday;
day(6) -> friday;
day(7) -> saturday.
任何传递给该函数的意外值都会导致错误,可以由另一个进程(即:监督进程)捕获和处理。这些错误也永远不会危及整个系统,并且不需要将代码添加到函数本身中 - 它是通过预定行为在正常执行路径之外完成的。 在动态语言中,快速失败不是常规操作,您必须手动检查边界并自行抛出异常。然后,如果您不想使整个系统崩溃,就必须在本地捕获异常(包括顶层 try ... catch)。错误处理代码通常必须插入整个正常执行路径中。 在静态语言中,快速失败不是常规操作,您的代码长度将高度取决于您的类型系统。如果语言允许定义类型,其中边界情况最终由编译器检查,则通常无需在代码内部处理此问题,除了非确定性事件(文件不起作用,意外用户输入等)外。在具有此类类型系统的语言中,许多错误将在运行时之前被捕获,因此您不必进行太多的防御性编程。 当无法避免错误处理时,支持快速失败惯用语的语言(例如Erlang)将允许比不支持的语言(静态或动态)更清晰的代码,主要是因为特殊情况的代码与理想执行路径的代码不混合。

5
请参考Joe Armstrong的论文第4.3节和4.4节。链接如下:thesis

链接已经失效,但这里有一个可用的链接:http://erlang.org/download/armstrong_thesis_2003.pdf - Michael Oliver
在我看来,第4.5节也很相关。 - toraritte

-4

快速失败编程风格注重代码可读性和调试。用户体验是次要目标:用户可能会遇到奇怪的错误消息或程序故障,但更高质量的代码使程序员能够轻松找到错误并纠正问题。

相反,防御式编程侧重于验证来自用户和其他代码部分的输入。代码更冗长,因为程序员必须仔细验证输入,并在出现错误时优雅地失败。这导致了更多的代码(从程序员的角度)和更强大的应用程序(从用户的角度)。


2
不正确。你混淆了快速失败风格和无错误处理风格。快速失败风格仍然允许程序捕获错误并从中恢复,而不会打扰用户。 - Deestan
3
很显然,使用failfast风格的软件也使用户受益匪浅。我更愿意说,failfast关注的是明确正确和错误输入,并实际执行这一点。明确性通常会产生更好的编程结果。输入中的错误应该被标记为这样的错误(而不是使应用程序跨入未定义的领域),但这并不妨碍应用程序优雅且直观地处理此错误。我认为您正在设立一个错误的二分法。 - harms
2
错误的答案。在Erlang的上下文中,更健壮的方法是避免防御性编程,只需让有问题的进程“崩溃”。另一个进程将采取适当的措施进行恢复。在您似乎有经验的Java中,您别无选择,只能进行防御性编程,因为它是一种具有共享状态并发模型的命令式语言。由于Erlang是一种具有消息传递并发性的函数语言,并且因为存在在进程之间通信故障的机制,因此快速失败是完全可以接受和优选的。 - dsmith
你确实做到了,frm,但你已经迈出了第一步:接受输入。你没有让自己的骄傲干扰你的成长。赞。 - JUST MY correct OPINION

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接