我现在还会偶尔想起大三的时候在一家小公司做Android开发实习生的经历。
那时候我还是个超级新手,但是有满腔的热情,所以学东西很快 (其实就是记住了很多API)。我自信心爆棚,但没多久,就被小组长的几次 code review 打碎了一地。
“常量名称怎么没大写?”
“这次提交的代码出现好多的typo(拼错的单词)“
”这个API不是这么用的,这边这么写太牵强了“
”这边用 sleep 几秒就能彻底解决问题吗?sleep几秒才合理?万一用户手机比较慢呢?“
”你这个函数长度都快几百行了“
”你这段代码的if else就像俄罗斯套娃“
... ...
那段实习经历让我成长了很多,虽然我最后并没有继续做Android开发,但是在那段时间中学到的很多经验和编码原则让我至今受益匪浅。
毕业后几年工作经验,我也逐渐总结出一些提高代码质量的思考
第一,对代码的要有洁癖
写代码不能有 “能跑起来就行了”“功能正常就行了”这类想法,否则你就会渐渐写出一堆一堆的屎山,其他人甚至你自己阅读代码时不仅辣眼睛还难以维护、扩展新功能。
举几个例子:
if else 不要频繁使用,甚至嵌套使用,尝试用多态来实现;
给每个变量/函数/方法/类/包都取上尽量合理且清晰明了的名字;
常量名要大写,变量名不要有错别字
...
除了这些比较基础的,还可以渐渐思考代码的结构,比如引入一些 设计模式 让代码结构更清晰,维护性更好 —— 参考我以前的一篇文章
总之,要让自己的代码看起来干净简洁可维护性高。
我推荐阅读 《Clean Code:代码整洁之道》和《重构:改善既有代码的设计》
第二,学习API的最佳实践
关于这一点,不仅是初级程序员我甚至看到有些高级程序员都在犯这类错误。
刚开始学习新技术或者新API总是令人兴奋的
“这个API还挺有意思的,下次写代码试试看!”
这时候的你,仿佛在地上捡到了一把锤子,看到什么东西都像钉子想上去锤几下。
于是你可能写出一些自己觉得很酷 但在老司机看来有点“搞笑”的代码,举两个例子:
Java 8 的 Optional
String names = Optional.ofNullable(httpServerRequest.params().get("name")).orElse(GENESIS_NAME);
参考我的文章
FreewheelLee:Java 8 Optional 最佳实践zhuanlan.zhihu.com
JavaScript 的 数组解构
const [age, name] = [person.age === null ? 0 : person.age, person.name === null ? '' : person.name]
看到这两份代码,你们是感觉自己膝盖中了一箭还是脸上泛起老司机的微笑?
我也犯过类似的错误,所以后来我学习新API时一定会去Google ”XXX best practices" 或者 “XXX 最佳实践”,去了解这个新API的设计初衷和最佳实践,让自己学会写出正确的代码。
此外,阅读 Effective 系列的书籍也是很有好处的,如 《Effective Java(第三版)》
第三,学习并坚持一些编码原则
比如
1. Open Closed Design Principle :对扩展开放,对修改封闭 —— 保持代码的可扩展性,实现新功能时尽量避免***修改原有代码
2. Single Responsibility Principle :单一职责原则 —— 每个方法每个类都尽量保持单一职责
3. Dependency Injection or Inversion principle :依赖注入(依赖倒置)——在一个类(文件)里,不要创建自己依赖的其他类的实例,而是由外部传入(这是 Java Spring 的核心设计之一)
4. Liskov Substitution Principle :里氏替换原则 —— 任何子类都该完全实现父类的功能,可以随意替换子类实现而使调用者不受影响
5. Programming for Interface not implementation :面向接口编程而不是面向实现 —— 从更高层次去设计,接口”不仅仅指Java的接口,还可以是包(package)甚至 API
等等
熟悉并理解并坚持这些编码/设计原则,会让你的代码质量渐渐提高。
我曾经多次在扩展新功能或者维护代码的时候感激当初自己的代码设计
”多亏了我当初这么设计了,现在做这个功能扩展太轻松了!“
我希望你们也能常有这种体验。
最后,正如我的专栏名称”码农的编程艺术“,希望你们也能把编程当作一门艺术,注重设计和细节,才能不断提高代码质量,成为一名专业的软件工程师。