90%的程序员都犯过的代码错误

新闻 前端
最近参加了多次的代码review会,在review的过程中,发现有些问题几乎每次都出现。挑了几个比较典型的问题讲解下。

 

最近参加了多次的代码review会,在review的过程中,发现有些问题几乎每次都出现。挑了几个比较典型的问题讲解下。这几个问题都是初级问题,解决方法都很容易。只要掌握了方法,有意识避免,能让短时间内迅速提高代码质量。真所谓投入小,见效快。

变量命名不清晰,一词多义

为变量命名时最重要的考虑事项是,该名字要 完全、准确地描述出该变量所代表的事务 。容易阅读,不会与其他事务混淆。

例如:

  1. if(staff_id == 0) 
  2.     printf("系统归档,不是员工归档"); 

上面这段代码,staff_id是员工号的意思,用staff_id为0表示是系统归档。一词多义,本来应该把系统和人分开,但是混用到了一个变量。如果调用方出现个bug忘记把初始化的变量赋值,还会走到意外的逻辑。

解决方法是变量名称首先要符合变量的实际意义,没有歧义;对于一个变量名,不用特定值表示特殊逻辑。

有些代码会把变量取不到的值赋予其他的意义,感觉是省事了,实际后患无穷。例如用户名不可能为空,就用空值表示这个用户数据已经被删除了。而且判定数据是否删除的代码看着也让人莫名其妙。

总之,变量命名要保证没有「潜规则」,防止给自己挖坑。

使用魔数

命名不清晰更严重的是,没有命名,直接用魔数。如果连注释都没有,就只能靠猜。

使用魔数有两个不好的地方:

1、不方便修改。

使用常量替换魔数是一种将程序「参数化」的方法,需要修改改动一处就可以了,而不必代码中到处修改。

例如在代码中默认绑定的端口是80,如果不用一个常量代替,哪天软件升级默认端口变成443了。要整个代码搜索80这个数字,既耗时,又容易改错。

2、代码不方便阅读。

只有一个数字,很难了解到具体的意思。

  1. for(int i = 0; i < 13; ++i) 
  2.     ... 

上面这段代码,只看13,谁能猜出来是什么意思呢,为什么用13这个数值?可能只有写代码的人和上帝知道,如果天长日久,写代码的人忘记了,就只有上帝知道了。

也有同学会问,有的数字只用到一个地方,也起个常量的名字会不会太麻烦了?

答案是:不麻烦。给魔数起个好名字是应该的,这是对的事,不要因为麻烦就不做。有时为了起个准确的名字,甚至要查下词典。

有一个常用的判定方式:

一、如果引用魔数的地方不超过3个,直接用数字影响也不大。如果超过了3个,都是表示同一个数值意义,还是乖乖地用有意义的变量名代替。

二、如果魔数本身就是表示一个纯粹的数字定义,例如是几米、几千克这种,作为参数传递。在函数的定义明确表示了形参数所代表的意义。大家看用到的地方和函数定义,就知道数字是表示多少个单位的意思,可以用魔数。但是如果用数字表示种类,例如

  1. const int ieBrowser=1; 
  2. const int chromeBrowser=2; 

表示浏览器的种类,如果直接只是看到1或2,是不明白什么意思的。即使在函数声明的地方已经说过是浏览器种类了,也不要用魔数。

魔数解决的办法很简单: 用枚举、常量等方式,代替魔数 。

if else 或switch等逻辑判断语句太长

例如下面的伪代码代码,条件分支很多,用很长的if else语句或者switch语句才能表达完整的逻辑,要思考下是否能用「表驱动」方式来优化。

  1. const int CN=1; 
  2. const int US=2; 
  3. const int UK=3; 
  4.  
  5. string language; 
  6. if(country==CN) 
  7.     language="中文"
  8. else if(country==US) 
  9.     language="english"
  10. else if(country==UK) 
  11.     language="english"
  12. else 
  13.     language=""

条件分支太多太长有几点不好:

1、代码太长,不易阅读。

如果超过了一个屏幕能表示的长度,要翻页才能看完代码,会大大降低看代码的效率。因为代码的信息密度太低了。

2、不易扩展,修改代码。

就像上面的例子,如果又增加了新的条件判断,那么要增加新的if else语句,由于修改了逻辑,要重新测试,也要防止改错。

可以用「表驱动」的方式替代太长的逻辑分支。

把每个条件要用到的数据放到一个「表」里。用条件分支的判断条件来索引到表中的数据。

上面的代码可以修改为

  1. const int CN=1; 
  2. const int US=2; 
  3. const int UK=3; 
  4.  
  5. string languageTable[]={"","中文","English","English"}; 
  6. //先判断country变量是否在定义的CN、US、UK范围内,如果在继续 
  7. language = languageTable[country]; 

经过修改,代码变得很短,一眼就能看出代码所表示的逻辑。而且以后更新的只有数据,逻辑部分不用修改。

使用「表驱动」后,逻辑和数据分离。使得新增数据修改简单,而且一目了然。

总结

上面只是简单的说明了几种常见的代码书写错误。稍加注意,就能够在短时间内迅速提升代码质量。具体的方法可以参考一些代码规范,或者重构的书籍,例如「表驱动」会有更详尽的介绍。

最本质的还是要从意识上有足够的认识。 代码是写给人看的 ,写代码时要有同理心,想到以后让阅读代码的人尽量能够不费力读懂。换位思考,如果你就是review人,或后面接手这个代码的人,你会喜欢这段代码吗?

毕竟代码阅读的次数远远超过编写的次数。确保代码阅读方便,而不仅是编写方便。

 

责任编辑:张燕妮 来源: 架构学而思
相关推荐

2015-03-02 15:30:11

2015-04-17 09:47:57

2011-06-29 09:27:10

2019-08-22 10:07:33

程序员开发危机

2018-10-15 09:50:07

程序员高薪淘汰

2021-11-02 09:54:51

Java开发工具

2020-04-20 18:15:46

开发自信技术

2021-09-28 09:57:50

程序员技能开发

2020-05-17 16:10:36

开发人员软件开发开发

2016-12-06 10:12:07

程序员开会

2022-10-17 07:40:21

AI项目数据

2017-03-13 09:07:05

测定代码基因

2017-11-14 11:28:49

程序员索引数据

2019-07-03 14:47:43

程序员祼辞就业

2022-07-20 16:57:18

程序员高薪职业

2019-07-05 11:05:10

Java程序员中间件

2013-08-20 09:33:59

程序员

2015-06-17 14:24:48

优秀程序员整洁代码

2018-07-20 11:22:03

程序员基础知识

2016-12-21 11:35:55

Python程序员
点赞
收藏

51CTO技术栈公众号