代码首先是写给人看的,只是恰巧(incidentally)能够运行。 ----Paul Graham
现在写C++服务后端,工作内容大部分是推荐系统后台开发。推荐系统算是公司技术架构中比较基础服务的模块,所以对代码质量的要求比较高。之前做游戏很多时候代码都是赶工的,也没有很好的静下来思考去重构,几天没事重构了之前的一个模块,重构后,代码可读性有了很大提升。
我们都知道要追求高质量的代码,什么是高质量的代码,这个标准就比较高了,但我们需要至少保证不写出很难维护的代码。平时每次的pr都需要被经理review,自己写代码的要求越来越高。
代码的坏味道体现在:
1.注释太多或者太少
整个代码都是很多的注释,整个屏幕没几行是代码的,想要看个整个代码还需要翻好几页,能够维护你的代码的人,能力都是和你比较接近的,别人还不是那么蠢。
每个人负责的功能还是有一点的不同,有时候的确遇到一些功能,实现起来比较曲折,如果不是自己写的别人很难理解错误,这时候需要额外注释一下,利于后来人的维护。
2.代码风格不统一
这个一般出现在新人的代码中,比如匈牙利命名和驼峰命名法交叉使用,看起来就让人厌恶,代码风格整体必须保持统一,整体看起来不那么乱。
std::vector<int64_t> gid_list;
std::vector<int> uidList;
3.函数命名
看一段代码,首先看到的是代码的函数名,好的代码,一看函数名就知道函数的作用,烂的代码,函数名字模棱两可,让人只能去读函数的每一行代码才能读懂。
bool check(int64_t gid); //1
bool isAvaliable(int64_t gid); //goods
对于一些检测函数,以肯定的语句更合适。
4.变量命名
初学者经常容易用t1,t2,t3等以字母加数字组合的方式来命名。变量命宁愿长点也不要太短。
比如要保存itemcf推荐的物品gid列表。
std::vector<int64_t> gids; //1
std::vector<int64_t> itemcf_gids; //goods
i,j,k一般仅用于for循环中的下标。推荐换为具体的下表定义单词。
5.代码一行字符太多
有的函数声明就好长的一行,要看完还得需要移动光标到最后,继续往后翻,这种看了就不想看,一般不要超过80字符,有些不可避免的过长,换行然后第二行插两个tab对齐。
6.函数体函数太长
一个函数体代表了一个模块的封装,如果函数的实现太长,有的甚至一屏幕都看不完,这时候你是不是需要考虑你的模块划分的有问题了,一般来说函数体平均不要超过50行,对于模块进行正确的划分。完全能够减少函数的行数,使得函数实现更清晰明了。
7.重复的代码
在实现功能的时候,完全只考虑怎么实现逻辑,完全没去想结构的调整,重复的逻辑出现了好几次,代码块看起来臃肿不堪,需要很大力气才能读懂。
面向对象的继承,多态,封装这些的出现都是为了解决代码复用的问题,对于重复的逻辑完全可以将重复的功能提炼出来,封装成一个函数,再去调用。
8.错误的设计
本来可以有的更简洁的实现,被实现的过于繁琐,让人看起来啰里啰嗦,打个简单的比方,需要保存一个列表,列表里每个元素只能唯一,如果被设计用vector去实现,还需要自己每次push_back时还需要手动去查找,如果一开始用set来存储,代码就会简洁很多。(这个例子貌似不大合适)
9.缺乏一定的抽象能力
主要体现在一个最初的一个简单需求,后来提了更多的需求,到最后一个功能有了好多的变种实现,功能代码很难复用,比如对于一个初期的推荐,最开始需要保存的数据只是物品信息表以及一些操作一个类ReposManger就够了,后期可能需要用户的浏览记录,心愿单,用户画像等,该类操作越来越多,需要管理的数据越来越庞大,架构都不敢随便动。这个主要体现在项目组里开发效率比较高的人,大量的业务开发工作导致没做过多的思考,要体会到这个坏味道需要一定的经验。
要消除这些代码的坏味道,只有通过多写,多思考,多看好的代码!