前言
很多时候,我们看到一些旧的代码,觉得它不可思议,怎么会有这么糟糕的代码,你会想是谁写了这么脏乱的代码(有时候会惊喜的发现是自己),然后你只能硬着头皮去读这些代码是什么意思,然后小心翼翼地修改其中某个东西,让你的工作完成,然后提交,over。
如此,代码在一次一次的提交中慢慢腐烂,最终变得散发出阵阵的恶臭味,然后甚至可能引发一些潜在的漏洞和危机(我听过有的公司因为项目代码实在维护不下去了倒闭了)。
所以说,代码的爱护太重要了,很多人觉得,让代码“能工作”就行了,然后开始下一个任务了,这是不够的。其实写代码和写文章、报告等很像,开始是把要表达的东西写出来,然后在慢慢斟酌、推敲,直至达成心目中的样子。
简介
《代码整洁之道》一书,从最简单的代码顺序、变量命名优化,到模式、系统优化等多个方面提出了一些建议和方案,让代码看上去更加简洁和易读。最后一章中,作者比较完整的列出了他在工作过程中的代码整洁优化经验,可以当成是这一本书的整体概要了,如果不想看前面,直接看第17章也能get到一些点,只是说不是很详细。并且,,前面有两章是拿到完整到项目代码一步一步实操优化过程,分解了作者的整个思路流程,跟着看其实还是挺有意思的,也能更加理解前面章节作者所讲的一些东西。
代码优化
接下来,,我们大概过一下一些我觉得对我比较有启发和感觉比较好的一些点吧
命名
首先是命名。一个好的名字非常重要,想想为什么我们自己取名字的时候,父母想破脑袋、或者花钱也要给我们取一个好听、好叫、好认的名字,同样,我们的变量名、方法名、类名、文件名等,一定要多花点时间好好想想怎么取,最好是能够一眼就看出来这个是什么意思。
private BroadcastReceiver mBroadcastReceiver;
private PublicNotifyReceiver mReceiver
比如这两个,看代码的时候,咦?这是什么广播啊,然后只能去翻看定义的地方,看看它注册接收了些啥广播,而且,这两个变量的命名,其实是毫无意义的,根本没有任何表示它是做什么用的!如果换成 appSettingChangeBroadcastReceiver
和 dialogPushBroadcastReceiver
呢?那我们是不是光看名字,就能知道第一个是“应用设置变更”的广播,第二个是“弹窗推送监听”的广播呢?好好取个名字就能省去阅读代码时的疑惑,何乐而不为呢。 所以,要让名字有确切的意义。
我们再来看一个命名,getHour(Calendar calendar)
,这是个工具类中的方法,可是我怎么都看不出它是干什么用的,开始我以为是获取这个Calendar的小时字段,又想过是获取当前的时间,其实呢,它是获取了HH:mm
这样一个格式化时间字符串。所以说它的名字和它做的事情根本不是一样的,这一方面让我们不得不点进去才知道里面做了什么,另一方面,这样的功能即使存在,但当我们习惯性的想用一个这个功能的方法,结果从方法名根本没看到有这样的方法,然后就重新写一个,这不是重复了吗?so,让名字有意义,并且,让他们表里如一,名字和做的事情是一致的。
注释
写代码过程中,我们会写很多注释,写注释也有很多要注意的东西,不是随随便便写的。
- 必要的时候才注释
不是什么地方都要写注释的,我们只要在一些比较复杂、或者功能比较特殊的地方,标明这里为什么这样写,就够了,多余的东西不要。
- 别写废话
/**
* 日期格式 -- yyyy年
*/
public static final String DATE_FORMAT_Y = "yyyy年";
/**
* 日期格式 -- yyyy年MM月
*/
public static final String DATE_FORMAT_Y_M = "yyyy年MM月";
比如这种,我们一看就知道这是干嘛的,为什么要浪费这么多行去写注释呢?有这个精力,我们可以在命名方面更好的想想,很多变量、方法其实可以直接用命名去告诉阅读者这是干嘛的,没必要什么都写上注释。
- 注释的格式
/**
* <b>Project</b> <i>almanac</i><br>
* <b>Create Date</b> <i>2014/10/18</i><br>
* <b>Author</b> <i>***</i><br>
* <b>Email</b> <i>***@mmclick.com</i><br>
* <b>Update Date</b> <i>2014/10/18 14:49</i><br>
* <b>Last Update</b> <i>***</i><br>
* <b>Description</b> <i>
* <p/>与时间有关的工具类
* </i>
*/
public class TimeUtils {
...
}
看这个在类名上面的注释,真的是看着特别难受啊!第一,在java代码中混入html语言的注释,或许你会说在导出doc的时候会很规范,但是其实并不怎么会导出doc,并且,我们大部分时候,还是在ide或者文本编辑器中去阅读这段代码,然后各种标签混在一起,给阅读造成极大的不便,这样的格式简直太让人头疼。
第二,注释的都是些没用的东西。现在的版本管理工具,能给我们记录很多信息,包括类的创建者、创建时间、更新时间,这在注释中完全没有任何必要出现。
第三,描述多余。我们一般看到以Utils结尾的都知道这表明是个工具类,TimeUtils,那就是时间相关的工具类咯,这么一来,上面的描述又有什么作用呢?
别写重复代码
别写重复代码,别写重复代码,别写重复代码,将一些多个地方都要用的代码抽取封装出来,这个不多讲了,很简单也很重要。
函数
首先是函数代码量,正常我们编辑器一屏显示的函数一般在30-40行左右,我们应该控制函数在一屏之内结束,让函数短小精悍。
职责单一。我们应尽量让一个函数只做一件事情,不要让太多功能混在一个函数中,如果确实做了很多事情,那一定要好好对该函数命名,不能以其中一个功能命名整个函数。
参数不要太多。最理想的参数数量是零,其次是一,再次是二,应尽量避免三。有足够特殊的理由才能用三个以上的参数。
函数顺序。我们阅读代码的时候,往往都是从上往下的,所以我们在写函数的时候也要注意,先出现的函数在上面,函数中有调用其他函数,那就紧随其后,这样看代码的时候就不用跳来跳去,我是谁,我在哪,我要回哪里....
例如我这个Activity中的一个onCreate方法,首先一眼就能看出这里面做了些什么,然后跟着执行顺序一步一步往下看,整个过程不需要跳转任何地方,一下就能知道进入该页面后,我的处理流程是怎么样的。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.alc_activity_home_layout);
linghitSecurityCheck();
initView();
initWork();
addDialogs();
initAfterUiShow();
handleDelayTask();
}
函数顺序(按Ctrl+F12就能出现)
WX20200111-214240@2x.png
设计
整个代码结构的设计,这个没有说一定要设计得多么复杂,关键是要好用,好读。不过这个也是要在经验积累的基础上,慢慢多写写就可以啦。多看别人写的比较好的一些结构,先抄,然后慢慢改,逐步做成自己想要的样子。
写在最后
特别喜欢书本开头引用的一句话:“让营地比你来的时候更干净!”
如果每次签入时,代码都比签出时干净,那么代码就不会腐坏。清理并不一定要花多少功夫,也许只是改好一个变量名,拆分一个有点过长的函数,消除一点点重复代码,清理一个嵌套if语句。
每个成员,每一次迁入代码都能做到这一点,那么代码就不会腐烂。
最后,推荐大家阅读《代码整洁之道》一书~
网友评论