“Null 是价值十亿美元的错误!”

“不健康”的代码到处都是Null检查!

作者 |James Hickey

译者 | 弯月,责编 | 郭芮

出品 | CSDN(ID:CSDNnews)

以下为译文:

你是否知道提出“null”这个概念的人声称这是他的“十亿美元错误!”

这个问题看似很简单,然而一旦你深入大型项目和代码库,就必然会发现有些代码中null的使用简直匪夷所思。

有时,我们希望使对象的属性为可选:

在TypeScript中,string类型的属性值可以为null。

但是,number属性居然也可以!

呃……

再举个例子

乍一看去,似乎并没有什么不妥。

但是,这可能会引发如下情况:

这段代码有什么问题?它会让你的代码(上述代码中的Product类)陷入不一致的状态。

系统中的Product没有id,这合理吗?应该不合理吧。

理想情况下,一旦创建Product,它就应该有id。

那么,在需要与Product打交道的其他地方会怎么样呢?

实际情况惨不忍睹:

真的有人写这样的代码?

有!

在介绍如何修改上述代码之前,首先让我们来看一看为什么这段代码不健康,然后再考虑“代码的味道”。

这段代码很糟糕吗?

这段代码非常难以阅读和理解。因此,在修改这段代码时很容易出bug。

应用中塞满这样的代码可不是什么好事,你也同意吧。尤其是当在应用程序的重要以及关键部分出现这样的代码!

关于TypeScript中的不可为null类型

有人可能会想到,TypeScript支持不可为null的类型。

你可以在编译选项中添加一个特殊的标志,该标志默认情况下会禁止给任何变量赋值null。

关于这个观点我还有几点想说:

我们大多数人都需要处理现有的代码库,如果想修复这些编译错误就需要付出大量的时间和精力。

如果不进行严格的测试且小心地避免作出任何假设,那么这些修改仍可能造成运行时错误。

本文中谈到的解决方案也同样适用于其他语言,即便这些语言可能没有这样的选项。

无论怎样,安全的做法还是更有针对性地改进代码。同样,这可以确保系统的行为不变,而且还可以避免在修改的时候引入大量风险。

一种解决方案:Null对象模式

空集合

想象一下,你在一家为处理法律案件编写软件的公司工作。

有一天,在开发某项功能时,你看到了如下代码:

记得我们应该谨慎使用null检查吗?如果代码的某个地方忘记了检查null数组,就会造成大问题。

Null对象模式可以帮助你:你可以创建一个代表“空”的对象或null对象。

修改代码

让我们来看看fetchCasesFromAPI()方法。我们可以使用这种模式,而且在JavaScript和TypeScript 中处理数组时,这种做法很普遍。

为了避免空数组/集合的值为null,我们将一个空数组赋给它。

这样一来,别处就不需要检查null了!

但是,整个legalCase怎么办呢?如果这个API返回null,该如何是好?

搞定!

现在我们可以确保每个使用该方法的人都无需再担心null检查了!

示例2

在C#、Java等其他语言中,由于强类型的规定,你不能将一个空数组(即[])赋给集合。

这时候,你可以使用Null对象模式:

对象又如何呢?

想象一下,你正在开发一款视频游戏,你在某些级别设定了大boss。

在检查该级别是否有大boss的时候,你可能会遇到如下代码:

我们可能会发现其他地方也有这类的null检查:

我们只需引入一个null对象,就可以省却这些所有的null检查。

首先,我们需要一个表示大boss的接口:

接下来,我们可以创建一个boss类:

然后,我们创建IBoss接口(代表一个“null” boss)的实现:

这个NullBoss会自动让玩家“通关”,所以我们就可以删除所有的null检查了!

在如下代码示例中,如果boss是NullBoss或Boss的实例,也不需要额外的检查。

如何保证代码的健康?可以参考《Refactoring TypeScript 》一书中的部分内容,这本书旨在通过易于入手且实用的工具,帮助开发人员更好地构建高质量的软件。

原文:https://dev.to/jamesmh/unhealthy-code-null-checks-everywhere-2720

本文为 CSDN 翻译,转载请注明来源出处。

【END】

热 文推 荐

华为发布麒麟 990 芯片;苹果召回部分电源插头转换器;KDevelop 5.4.2 发布 | 极客头条

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190908A07UFA00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券