|
|
《Clean Code》之代码坏味及启发
注释
- 不恰当的信息 注释只应该描述有关代码和设计的技术性信息,而不是那些本应该在源代码控制系统中保存的信息。
- 废弃的注释 注释很快会过时。废弃的注释应及时删除
- 冗余注释 若果注释解释的是一目了然的东西,就是多余的
- 糟糕的注释 如果值得编写注释就好好写,保证正确的语法和拼写
- 注释掉的代码 注释掉的代码吗污染了所属模块,放散了注意力。应该删除!
环境
- 需要多步才能实现的构建 构建系统应该是单步的小操作——应当能够用单个命令签出系统,并用单个指令构建
- 需要多步才能做到的测试 应该发出单个指令就可以运行全部单元测试
函数
- 过多的参数 函数参数应该少
- 输出参数 输出参数违反直觉。若果函数非要修改某东西的状态,就修改它所在对象的状态
- 标识参数 布尔值参数的存在就意味着函数不止做了一件事,应该消灭
- 死函数 永不调用的函数应该丢弃
一般性问题
- 一个源文件中存在多种语言 理想的源文件有且仅有一种语言
- 明显的行为未被实现 函数或类应该实现其他程序员有理由期待的行为。通过函数名的直觉应该能够理解函数的行为
- 不正确的边界行为 代码应该在所有的边界情况下都能工作。别依赖直觉。探寻每种边界条件,并编写测试
- 忽视安全 不要忽视编译器的警告和错误
- 重复 重复的代码,意味着遗漏了抽象。尽可能找到重复并消除它
- 在错误的抽象层次上的代码 创建分离较高层级一般性概念与较低层级细节概念的抽象模型。所有较低层级概念放在派生类中,所有较高层级概念放在基类中
- 基类依赖于派生类 如果看到基类提到派生类名称,就可能出问题了
- 信息过多 设计良好的模块有着非常小的接口。应该限制类或模块中暴露的接口数量。
- 死代码 不执行的代码应该从系统中删除
- 垂直分割 变量和函数应该在靠近被使用的地方定义
- 前后不一致 消息选择约定,一旦选中,就消息持续遵循
- 混淆视听 保存源代码整洁,良好的组织
- 晦涩的意图 代码要尽可能居有表达力。联排表达式、匈牙利标记法和魔术数都遮盖了作者的意图
- 位置错误的权责 代码应该放在读者自热而然期待它所在的位置
- 不恰当的静态方法 倾向于选用非静态函数。如果的确要静态函数,确保没机会打算让它有多态行为
- 使用解释下变量 把计算过程打散成一系列良好命名的中间值,不透明的模块就会突然变得透明
- 函数应该表达其行为 应该能从函数调用中看出函数的行为
- 理解算法
- 用命名常量代替魔术数 魔术数现在不仅指数字,泛指任何不能自我描述的符号
- 准确 对自己做的决定,确认足够准确。代码的执行要能保证准确性
- 结构甚于约定 命名约定很好,但却次于强制性的结构
- 封装条件 应该把解释了条件意图的函数抽离出来
- 避免否定性条件 否定式条件要比肯定式难理解,尽可能将条件表示为肯定形式
- 函数只做一件事情
- 函数应该只在一个抽象层次上 函数中的语句应该在同一抽象层级上,该抽象层级应该是函数名所示操作的下一层。
- 在较高层次放置可配置数据 位于较高层级的配置性常量易于修改。它们向下贯穿应用程序。应用程序的较低层级并不拥有这些常量的值
- 避免传递浏览 不要让某个模块了解太多其协作者的信息。确保模块只了解其直接协作者而不了解整个系统的浏览图。
名称
- 采用描述性名称
- 避免编码 不应在名称中包括类型或作用范围信息
- 名称应该说明副作用 名称应该说明函数、变量或类的一切信息。不要用名称掩盖副作用
测试
- 测试不足
- 使用覆盖率工具
- 别忽略小测试
- 被忽略的测试就是对不确定事物的疑问
- 测试边界条件
- 全面测试相近的缺陷
- 测试失败的模式有启发性 完整的测试用例、按合理的顺序排列,能暴露出通用性的问题
- 测试覆盖率的模式有启发性
- 测试应该快速
|
|