让软件能工作和让软件保持整洁,是截然不同的工作,后者需要投入的更多。
大多数人只能更多地把精力放在让代码能工作,而没办法保持代码有组织更整洁。能做到代码整洁,说明你已经不是一般人了。
什么样的代码是整洁的
取个好名字
让函数再整洁一点
注释的好与坏
格式化
异常处理和边界
整洁的类
不整洁的代码,阅读体验是这样的:
1.乱(组织乱,职责乱,名称乱起)
2.逻辑不清晰(if-else 太多)
3.绕弯子(简单的事写的很复杂)
4.看不懂(只有写的人能理解)
5.难修改(耦合严重,各种写死)
整洁的代码,阅读体验是这样的:
1.清晰(是什么,做了什么,一眼看得出来)
2.简单(职责少,代码少,逻辑少)
3.干净(没有多余的逻辑)
4.好拓展(依赖的比较少,修改不会影响很多)
接下来介绍一些写整洁代码的方法。
先看几个坏命名的例子:
正如上图所示,坏命名具有这样的特点:
1.使用缩写(让使用者误解其用途)
2.描述性差(通过命名无法理解他的作用)
3.相似(使用类似的、难分辨的名称)
4.使用专业术语做名称
容易误会,比如使用 Activity 表达活动,容易被理解成安卓里的组件
5.需要借注释解释
名称本身就是解释,如果还需要借助注释,就已经说明这个命名有问题,对应的类、函数、属性职责不清晰
好的命名具有这样的特点:
1.名副其实
阅读名称就知道它为什么存在、做什么事、应该怎么用,如果需要通过注释来回答,那就不算名副其实
2.不容易混淆
避免使用非常相似的名称,尤其是类型还相同,比如小写 l 和1、o 和 0、专有名词
3.读的出来
不要因为害怕名称过长而使用缩写,那样不便于和别人讨论
4.方便搜索
名称长度和其作用范围成正比,作用范围比较大的,长名称也可以,只要能表达清楚
函数的第一要则:短小 (多短才算可以?不超过 10 行,缩进层级不该大于两层)
只做一件事 (要判断函数是否做了不止一件事,就看它里面的代码,是否能再拆出一个函数)
函数变大的头号凶手:switch 语句
switch 语句天生要做多件事,我们能做的,就是减少 switch 语句的次数,把它埋藏在较低的抽象层级,同时不重复使用 switch
如果有类似的 switch 出现多次,就要考虑使用多态来减少 switch 语句出现的次数
定义的函数的参数越多,你耗费函数使用者的青春就越多,使用者需要花时间搞清楚每个参数的具体含义和顺序
最理想的参数数量是 1~2
从测试的角度看,参数越多,可能出现的用例就越多,就越容易出错
保持参数列表短小的方法: 参数升为全局变量、多个参数封装成一个类
不要有副作用(副作用就是做了名称以外的工作)
Android Studio 提供了 Refactor Extract ,帮助我们做代码拆分
在这些场景下,使用注释比较好:
1.弥补代码表达意图的失败
代码本身无法说明意图,这时使用注释,说明这段代码需要被修改
2.提供信息
提供代码以外的信息,比如产品相关信息
3.复杂实现的简要概括
让阅读者快速了解某个复杂的系统
4.警示、提醒
比如某个不起眼的代码是为了解决某个 bug,防止别人误删
5.TODO
IDE可以定位 TODO 注释,我们需要定期查看这些注释,删除不再需要的,让代码整洁
这些注释是坏注释:
1.令人费解的注释
读懂花费的时间比看代码的时间还长,差评
2.误导性注释,老旧的注释
代码才是真相,注释有可能是谎言,还是要”少写注释!“
3.日志型注释
比如记录修改日志,放到 git commit 日志里吧
4.废话注释
变量名、函数名已经很清晰,就不需要注释,注释里不要放一些奇怪的东西,比如如来佛祖
5.注释掉的代码
没用的代码及时删除
1.团队最好统一格式化标准
那样就可以避免某人只修改了一点,但顺手格式化了一下,整个类都产生了变动,那样会覆盖真正的提交日志。
2.一行代码列数不超过 100
Android Studio 里的竖线默认是 100,不要超过这条线。
3.代码抽象层级逐渐递减
最顶应该给出高层次概念和算法,向下逐渐展开细节。
4.用好空行
每个空行代表思路的重新开始,用空白行隔开思路和不同作用的代码,和写文章一样,及时分段。
5.物以类聚
关系密切的代码应该靠近。
异常处理:
1.使用异常替代返回错误码
2.抽离错误处理
如果错误处理很重要的话,可以考虑把错误处理单独放到一个方法里。
3.尽量不要返回 null
返回空对象好于返回 null,尽可能的避免空指针的出现。
4.慎用 CheckedException
定义异常时,要考虑它会被如何捕获。CheckedException 如果不处理,就得强制抛出去,那样会影响所有调用链。
边界:
1.处理逻辑前,优先处理边界和异常
2.快速了解某个框架的边界
在使用的框架代码里使用关键字 throw new 进行搜索,看看什么情况下会抛出什么异常,最后整理出来。
3.创建边界代码,隔离第三方
使用我们控制不了的代码时,必须加倍小心,确保未来修改的代码不会太大。
创建边界代码,隔离第三方,避免我们的代码对第三方框架内部了解过多。
整洁的类应该具有以下特点:
1.职责少,等于短小
评价类职责的多少,看它对外暴露的方法个数,多于 5 个就可以拆分了。
2.只有一条被修改的理由
根据单一职责原则,类应该只有一条被修改的理由。
3.隔离改变
依赖抽象而非具体;减少对外暴露公有变量,使用 getter 代替。
4.拆分不是坏事
有同学可能会担心了:拆分类太多会不会更复杂了?
假如你有很多东西,是希望根据分类放放到不同的小抽屉格子里,还是希望一起放到几个大抽屉里?
推荐阅读
回顾我这一年多的提交日志
跳槽需要内推?这里有一大波机会
当产品经理在群里艾特你有 bug...