一份拥有良好可读性和拓展性的代码是项目里的良药,它不仅看着舒服,改起来也方便,甚至还能重用,各模块逻辑分明。“见码知功底”,而要达到高手那种简洁有力的境界,需要进行大量的总结和练习,今天我们就来谈谈如何写出优美的代码。
命名
好的命名应该具有如下特征:
1,意思正确。这是最基本的要求,不要挂羊头卖狗肉,词不达意,要一眼就知道什么意思。就算一眼看不出来,复制到有道词典翻译一下也能知道什么意思;
2,单复数分明。如果是一个数组,要么加s/es结尾表明其是复数,要么加入list表示它是一个数组。如cars,carList都可以表达一个车的列表;
3,慎用缩略词。缩略词可以让我们的命名更加简洁,但是一!定!要!是!业!界!通!用!缩!略!词!比如info原意为information,msg原意为message,fn原意function,conf原意config等等,这些缩略词都是业内传统了,大家都知道什么意思,切记不要自作聪明乱造缩略词;
4,有具体含义。根据业务场景去命名,而不是根据抽象命名;比如getUnreadMsgList,一看就知道是获取未读消息列表的意思,而getData这种说了跟没说一样,缺乏具体含义。
注释
有表达力的代码是不需要注释的。比如一个init函数,一看就知道是用于做一些初始化的工作,没必要写多余的注释来说明。
但是有一些场景注释是非常有必要的,下面几种场景要添加注释:
1,一些针对特殊业务场景而订制的特殊逻辑。比如当我们更新个人信息的时候,由于后端的问题,需要少传一个诸如生日的信息,或者更新头像时要多传一个时间戳来供其他业务以后使用。这些莫名其妙的增删属性,如果不加以注释,将导致后续自己都无法理解;
2,可能会出现隐患的代码。由于自身水平所限,或者本身技术上就无法实现,只能通过一些特殊技巧来仿制一些效果,往往会存在安全隐患,比如:用户操作太快会出问题,网络太慢会出问题,某个接口调不通这页面会全挂了,一些特殊的操作会引起的暂时无法解决的bug等等场景,都需要注释说明;
3,涉及到某些高深的或者生僻的技术知识。这种也要注释,以提醒自己和其他开发者。
总的来说,在注释里“为什么这么做”比“这玩意是什么”重要得多,注释不要滥用,也不能不用。
函数
函数是代码的灵魂,也是写逻辑的载体,以下几个要求是判断一个开发者函数写的好不好的标准。
1,是不是单一职责。一个函数应该只做一件事,而这件事应该能通过函数名就可以清晰的展示。这是一个非常好的特性,一个辣鸡的函数可能动辄几百行代码,各种逻辑堆积在一起,看得人头脑发晕,甚至开发者自己都理不清楚;判断这个函数是不是单一职责的技巧很简单:看看它还能不能再拆分。
2,有没有层级之分。函数与函数之间是有身份地位之分的,有负责整体大局观的高级函数,也有专注细节的打工仔低级函数。如果不建立起层级结构,就容易迷失在细节的海洋里。比如:
对于做一顿饭这个函数来说,他不需要关心诸如买菜时反复挑选这种细节,它只需要知道,大概有三个大步骤就行了。所以这段逻辑会根据其地位拆分出不同等级的函数,假设没有层级之分,那么从第一步的“搭公交”一直写到最后一步的“倒垃圾”,这东西会变得极难维护。
3,承载的场景是否足够简单。有时候我们会遇到这样一种场景:一个函数在很多地方都会用到,但是不同地方传入的参数不一样,这样我们为了函数的通用性,就针对入参做了很多种场景的识别,导致入参非常多,里面还需要根据不同的场景做逻辑上的细微调整。所以单单是取传入参数都够呛了,一堆的if else或switch case。
这个函数太难了,而且这已经违背了函数的单一职责原则,它在里面做了多种场景的判断,从而表现出不同的行为,但这些行为又不是完全不同,而是“大体相同”,如果重写好像又会增加很多的重复的代码。解决的方法是做更小粒度的拆分,将那些真正与业务脱钩的部分抽离出来,而不同场景对应不同的处理函数,刚刚抽离的业务脱钩函数正好作为这些不同场景函数公共部分!