总结看完《代码整洁之道》这本书之后得到的CheckList,可以用来指导之后的代码review和重构。
命名
- 名副其实,替换更好的名字
- 使用有意义的变量名
- 用可搜索的名字
- 类名使用名词,方法名使用动词,方法名+参数使用动词短语
- 一个概念一个词
- 良好的描述技巧,共同的文化背景。
函数
- 函数要短小。一个函数只含有一个if-else
- 只做一件事
- 一个函数一个抽象层级。
- 描述性的名称。
- 参数越少越好。
- 使用异常代替错误码。
- 消除重复,提取出公共方法。
- 持续打磨,精益求精。
注释
- 注释是代码表达的失败
- 一般注释都不会得到维护。
格式
- 单个文件(class)的最大限制是500行,多数应该小于200行。
- 像报纸一样,先给出大纲,再逐个给出细节实现。
- 不同概念的代码块用空格区分开。
- 减少不必要的空行或注释分散注意力。
- 团队内使用统一的IDEA格式器,避免代码风格不一致。
对象和数据结构
对象暴露行为,隐藏数据(Service类)。数据结构暴露数据,没有明显的行为(DTO类).
遵守德墨忒尔律,模块不应该了解它所操作对象的内部情形。
比如这样的代码:
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath()
可以修改为:
Options opts = ctxt.getOptions();
File scratchFile = opts.getScratchDir();
final String outputDir = scratchFile.getAbsolutePath();
这样的代码依然不好,只是要获取outputDir而已,为什么这个函数要关心Options和File对象?
所以更好的实现方式是,把获取outputDir的实现交给ctxt封装起来。
String outputDir = ctxt.getOutputDir();
错误处理
使用异常而不是返回码,可以避免很多冗余的检查。
避免使用可控异常,这违反了开闭原则,当底层实现新增一种异常的时候,上层代码也要跟着一起修改。
publc String getSomething throws NullPointException(){};
给出异常的上下文环境,否则抛出的异常没有任何意义。
依照需要定义异常代理类。通过代理类来处理各种异常情况。
定义常规流程,使用策略模式来处理异常情况。
别返回null值,使用空的对象或容器来代替,避免if判断和空指针异常。
边界
封装对于第三方接口和类的调用,这样就把可能的改动限制在封装对象内部,避免第三方接口的修改对自身系统带来的过分影响。
或者可以使用Adapter模式,将我们的接口转换为第三方提供的接口,这样也实现了对第三方接口的包装。
类
类应该短小,体现出来就是一个类应该只有一个权责,当你发现无法准确定义一个类的name时,就该拆分这个类了。
单一权责原则认为,一个类有且只有一条修改的理由。
什么是高内聚?一个类内部应该只有少数变量,这些变量在所有函数中都被使用到。保持高内聚就会得到很多短小的类。
面向修改编程,将系统的修改设计为新增扩展类(开闭原则)。