Code Review 是做次保证代码质量的重要手段。Steven Heidel 曾在 LinkedIn 负责 Code Review,点经他在本文总结了常见的做次代码问题并提出修改方案。 当我在 LinkedIn 工作时,点经工作的做次很大一部分内容是做 Code Review。在这个过程中,点经我发现一些人很容易犯的做次错误,于是点经把错误整理起来并分享给团队。 我看到的做次一个常见模式是: 上面的方法可能是很多新手工程师的做法,但这种模式会有问题。点经在我曾经参与的做次移动应用中,这种模式导致移动应用程序的点经故障。用户搜索开始后,做次我们的点经后端发生错误开始 throwing exceptions,但在应用程序的做次 API server 中并沒有 throwing exceptions。 因此,从应用角度看,前端会收到 200 个成功的服务器托管响应,然后显示空白的搜索结果给使用者,而团队却毫不知情。 如果 API thrown an exception,那我们的监控系统会立刻发现它,并能及时修复。 很多时候,当捕捉到异常后,我们倾向于返回 empty object。Java 中 empty object 的样例包括 Optional.empty()、null 和 empty list。这种情况经常发生在 URL 解析中。如果 URL 无法从字符串解析得到的话,不要返回 null,而要问问自己: URL 格式为什么是不合法的?这是一个需要在 upstream 解决的数据问题吗? 对于这种任务来说,empty object 并不是恰当的工具。如果出现异常行为,那么就应该 throw an exception。 基本而言,这条建议恰好与 stringly typed programming 相反。 我经常看到下面所示的代码: 用最具体的源码下载类型 (type)可以避免很多 bug。 现在问题是:好心的程序员为什么会写出糟糕的 stringly typed 代码? 答案在于外部世界不是强类型的。字符串有很多不同的来源,比如: 在上述场景中,我们应使用如下的策略来避免该问题:将字符串解析和序列化放在程序的边缘之处。 下面是这样一个样例: 这种方式有很多优点。立即发现格式错误的数据;如果出现任何问题,应用程序将提前 fails。数据被验证一次后,不必在整个应用程序中继续捕获解析异常。 此外,强类型使方法签名更具描述性,我们不再需要在每个方法上编写那么多的 javadocs。 Java 8 带来最棒的特性之一是Optional类,它代表一个可能存在也可能不存在的实体。 一个小问题: 唯一拥有自己缩写的亿华云例外(exception)是什么?答案是 NPE 或空指针异常。截至目前,它是 Java 中最常见的异常,并被称为价值 10 亿美元的错误 (https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare )。 Optional能让我们完全从程序中移除 NPE。但是,必须以正确的方式使用它。如下是关于使用Optional的一些建议: 我们应避免下面所示的方法: 上述不推荐使用的方法有哪些共同点?那就是它们都使用了 container objects 作为参数,比如 Optional、List 或 Task。 如果返回类型是相同种类的 container,那就更糟糕了(比如,param methods 接收 Optional,返回值也是 Optional)。 为什么呢? 1)Promise<A> method(Promise<B> param)要比 2)A method(B param)更缺少灵活性。 如果有一个Promise<B>的话,我们可以用 1),也能通过.map函数使用 2)(即promise.map(method))。 但是,如果只有一个 B 的话,我们很容易使用 2),但是无法使用 1),这样来看,2) 是更具灵活性的方案。 我喜欢将其称为“unlifting”,因为它与常见的函数式工具方法“lift”恰好相反。采用这种方式重写会让方法更具灵活性,对调用者更加易用。经验 1:当出现错误时 Throw an exception
经验 2:尽可能使用最具体的类型(type)
经验 3:用 Optionals 而非 nulls
额外建议:尽可能采用“Unlift”方法