不一致的代码:为什么你的代码总被吐槽难懂?
多数程序员都是在一个团队中工作,对于一个团队而言,一致性是一件非常重要的事情,不一致会造成认知的负担,通常程序员对于一致性本身的重要性是有认知的,但是大家对一致性都表现在比较大的方面,例如,数据库的访问是叫DAO还是较Mapper,通常来说不一致会表现在 命名不一致、方案不一致、代码不一致这三类问题
命名不一致
相对来说这点比较容易理解,不同的程序员在编写同一个功能时按照自己的习惯使用了不同的命名风格,在code review时统一成一致风格
方案不一致
指实现同一个功能时,使用了不同的方案,比如判断字符串为空,有的人喜欢自己判断,有的程序员会使用库函数
代码不一致
通常是实现某一类相似的功能时,每个人的方法大相径庭,通常是把不同层次的代码写在了一起,最典型的就是把业务层面的代码和实现细节的代码混在一起。解决这种问题的方式,就是通过提取方法,把不同层次的代码放到不同的函数里,而这一切的前提还是是分离关注点,这个代码问题的背后还是设计问题
这一小节总结其实只有一句话:保持代码在各个层面上的一致性
落后的代码风格:使用“新”的语言特性和程序库升级你的代码
我们讲的是因为代码不一致造成的坏味道,其中我提到的“方案不一致”,是因为随着时间的流逝,总会有一些新的方案产生,替换原有的方案。这其中,最明显的一个例子就是程序设计语言。从 C++ 11 开始,C++ 开始出现了大规模的演化,让之前学习 C++ 的人感觉自己就像没学过这门语言一样;Python 2 与 Python 3 甚至是不兼容的演化;Java 也是每隔一段时间就会出现一次大的语言演进,新的语言特性都是为了提高代码的表达性,减少犯错误的几率。所以,在实践中,我是非常鼓励你采用新的语言特性写代码的。
这里提几个比较“新”的语言特性
可选类型
空指针异常是最常见的错误类型,空指针的发明者 Tony Hoare 将其称为“自己犯下的十亿美元错误”,对于这个常见的问题,其实有一个完美的解决方案就是使用可选类型,先回答一个基础的问题,一个对象有类型和没有类型有什么本质的区别?答案是操作,当你拿到一个对象,如果你知道他是什么类型的那就可以知道它能执行那些操作,而对于js这样的动态语言就无法直接做到这件事,我们对于空指针的问题同样使用这个思路来思考一下,如果对象拥有一个维度是来描述自己可否为空,这样当你拿到这个对象时就知道该如何操作这个对象了,如果他不允许为空,那就可以肆无忌惮的访问这个对象的属性,而反过来允许为空的,那么访问这个对象属性时就必须使用一些特殊的校验,比如在语法层面提供一个安全的调用方式,例如Kotlin中 ?.
,这操作符的含义是 对于 b?.length
,若 b 为null返回null,否则会返回b的长度,而这个表达式的返回值类型是Int?
也就是一个可空的int类型。
对于Kotlin、Swift、TypeScript等语言都在于语法层面支持可选类型,Java中可以Optional容器来支持可选类型
函数式编程
这部分会单独的整理为一个博客