笔者深度阅读了代码整洁之道,阅读之后深刻理解,总结以下关键内容:
1.类的起名:
.类名要明确,不要啰嗦,例如:Product、ProductInfo、ProductData,这三个变量中能用Product来表示就不要用其它
.尽量用名词,不要用动词
2.变量
.变量名要起的有意义,最好不要起l,o这个的英文字母(容易与数字1,0混淆),读起来很模糊。
3.代码块
.if、else、while:不要出现过多且复杂的结构
.switch:将每个swtich都埋藏在较低的抽奖层级,而且永不重复。如果使用switch去创建对象,利用多态、工厂的方式创建。
4.函数:
.函数名要使用与模块名一脉相承的短语、名词和动词给函数命名。
.函数名一定要具有描述性:函数越短小、功能越集中,越便于起取个好名字。长而具有描述性的名称要比描述性的长注释好。
.函数一样要短小:方法内容不该有100行那么长,20行封顶最佳。
.每个函数只需要做一件事。做好这件事。只做一件事。
.判断一个方法是否只做了一件事:就是看是否能再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。
.自顶向下阅读代码,向下规则:要让每个函数的后面都跟着下一抽象层级的函数。
.如果每次方法都返回错误码会造成上层程序的判断复杂、混乱。所以要使用异常替代返回错误码代替。
.错误处理就是一件事,因此处理错误的函数不应该做其他事。如果try在某个函数中存在,它就是该方法内部实现的第一个单词,而且在catch/finally代码块后面也不该有其他内容。使用异常代码错误码的好处:新异常可以从异常类派生出来,无需重新编译和重新部署。
.拒绝重复代码,重复可能是软件中一切邪恶的根源:重复代码由于业务的变更而修改,很有可能这些代码和其他模块之前冗余,不但难以修改而且还会漏掉,对系统造成不可预估的问题。
5.参数
.参数个数尽量不要多于两个
.有输入参数,无输出参数的形式称为事件(event),函数名要谨慎的选用名称和上下文语境。
.参数不要传boolean值标识,若传入该参数,方法做的就不是一件事了,错误例子:render(Boolean isSuite)。应该把方法一分为二:renderForSuite(),renderForSingleTest()。
.如果函数看来需要两个、三个或三个以上的参数,那就说明其中一些参数应该封装为类了。
.避免使用输出参数
大师写代码就跟写故事一样,描述系统中发生各种行为的函数层级。
6.注释
.能用函数和变量就别用注释。
.括号后面的注释:如果发现自己想标记右括号的注释,其实应该做的是“缩短函数”。
.每次迭代修改代码时,不需要标注修改者,修改时间,因为源代码控制系统是这类信息最好的归属地。
.项目中没有用的代码一定要将它删除,不然其他人看到了也不知道这段“被注释”的代码是做什么用的,也不敢将它删除。
.函数头不需要太多描述。为只做一件事的短函数取个好名字,通常比写函数头注释要好。
7.格式
.变量:应该声明在短小的函数顶部。在较长的函数中,应该声明在代码块的顶端。实体变量应该声明在类的顶部。
.相关函数:若某个函数调用了另一个函数,就应该把它们放在一起,而且调用者应该尽可能放在被调用者的上面。
.概念相关的代码要放在一起,例如方法的重载,它们拥有共同的命名模式,执行同一基础任务的不同变种。互相调用是第二位的。
.团队中一定要用统一编码格式化风格。
.对象与数据结构的二分原理(详细请看书中示例)。
.善于使用DTO(Data Transfer Object):最为精炼的数据结构,是一个只有公共变量,没有函数的类。
8.错误处理
.善用try-catch-finally
.将catch中的异常信息传递出去并打印到日志记录下来
.自定义异常类,推荐使用不可控异常如:RuntimeException。所谓可控异常就是受检查异常:它的代价就是违反开放/闭合原则,举个例子:如果你在方法中抛出“可控异常”,而catch语句在三个层级之上,你就得在catch语句和抛出异常之间的每个方法声明中声明该异常。因此破坏了程序的封装结构。
.如果要编写一套关键代码库,则可控异常有时也会有用:你必须捕获异常。但对于一般的应用开发,其依赖成本要高于收益。
.函数中不要返回null,尽量“抛出异常"或者返回"特例对象"。
例子:
public List<Employee> getEmployee() {
if (.. there are no employees ..) {
return Collections,emptyList();
}
}
如:如果函数返回的类型是List<>,该方法可能返回空的话建议使用Collections.emptyList()方法,该方法返回一个预定义不可变的列表。这样编码就能尽可量避免NullPointException的出现,代码更简洁了
.要将错误处理隔离对待,独立于主逻辑之外,就能写出强固而简洁的代码。
9.边界
.使用第三方代码库时,边学习边测试,再第三方代码包更新的时候还能及时发现是否与我们的项目想要的效果一致。
.使用尚不存在的代码:开发程序时,经常会调用外系统的API,可能有的API还没有设计出来,我们要自己模拟一个以后即将要存在的接口来完成我们的系统调用,这样API设计出来我们就能无缝衔接。
10.单元测试
.测试代码一定要具有可读性。
.将共用的断言方法抽离到@before测试方法中。
.每个测试方法只测一件事。
11.类
.类的组织,出现位置排序:公共静态常量、私有静态变量、私有实体变量(很少有公共变量)、公共函数、私有工具函数紧随其后。
.类的内容要短小,类的名称应当描述起责任,不要拥有过多的权责。
.类具有单一职责:系统应该由许多短小的类而不是少量巨大的类组成。每个小类封装一个权责,只有一个修改的原因。并与少数其他类一起协同达成期望的系统行为。
.开放闭合原则:类应该对扩展开放,对修改封闭。
.依赖倒置原则:类应当依赖于抽象,而不是依赖于具体细节。
12.系统
.使用AOP代理模式降低耦合。
.采用一些新技术,就能将架构按需从简演化到精细。没必要先做大设计。
.无论是设计系统或单独的模块,别忘了使用大概可工作的最简单方案。
简单设计的三条规则:消除重复,保证表达力,尽可能减少类和方法的数量。
13.迭进(后期维护迭代新需求)
网友评论