需要强大的软件?让它变得脆弱

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

在任何软件项目中,目标都是创造稳定的东西。我们不希望它在用户面前崩溃。我们也不希望我们的网站显示“内部应用程序错误”而不是网页。我们希望我们的软件能够正常工作,而不是失败。这是一个完全合理且合乎逻辑的愿望,但为了实现这一目标,我们必须让我们的软件尽可能脆弱。这听起来可能违反直觉,但事实就是如此。您的应用在开发中越 脆弱 ,在生产中就越 健壮

埃米尔·库斯图里卡 (Emir Kusturica) 的《黑猫,白猫》(1998)

所谓脆弱,我指的是 Fail Fast 哲学,它与 Fail Safe 相反。我相信您知道其中的区别,但无论如何让我通过示例提醒您。这是故障安全:


 public int size(File file) {
  if (!file.exists()) {
    return 0;
  }
  return file.length();
}

此方法应该计算并返回文件大小。它首先检查文件是否存在。如果不存在,该方法返回零。实际上,该文件不存在,因此没有大小。我们可以抱怨文件不存在,但这是为了什么?为什么要发出声音?让我们保持安静并返回零。我们不会失败,因为我们试图让应用程序保持运行。这称为故障安全。

相反,这就是 Fail Fast 的样子:


 public int size(File file) {
  if (!file.exists()) {
    return 0;
  }
  return file.length();
}

我们找不到文件?我们不隐瞒这个事实。我们将这种情况公之于众。我们尖叫和哭泣。我们抛出异常。我们 希望 应用程序崩溃、中断和失败,因为有人给了我们一个不存在的文件。我们抱怨和抗议。这称为快速失败。

哪种哲学,如果我们到处都遵循它,将使我们的软件健壮且具有故障恢复能力?只有第二个——快速失败。

为什么?因为故障发生得越快越容易,修复起来也就越快。而且修复会更简单,也更明显。 Fail Fast 是一种更好的可维护性方法。代码变得更清晰。跟踪故障要容易得多。即使是最微小的问题,所有方法都准备好中断并抛出异常。

在此示例中,如果该方法返回零,则不清楚文件是否存在且其大小实际上为零,或者其名称是否错误而只是找不到。 Fail Safe 方法 隐藏了 问题并使代码更难维护,这就是它难以稳定的原因。

一开始,在生产过程中,我们会遇到很多崩溃和错误。但是所有这些都将是可见的并且易于理解。我们将修复它们并用单元测试覆盖它们。每个修复都会使我们的软件更 稳定 ,并更好地被测试覆盖。

考虑到 Fail Safe 方法设计的软件在开始时看起来会更稳定,但它会迅速退化并不可避免地变成无法维护的混乱。

考虑到 Fail Fast 方法设计的软件在开始时会经常崩溃,但每次修复都会提高其稳定性,并最终变得非常稳定和健壮。

这就是为什么脆弱性是稳健性的关键成功因素。