1.1 要有代码
1.2 糟糕的代码
稍后等于永不
1.3.1 华丽新设计
1.3.2 态度
1.3.3 迷题
1.3.4 整洁代码的艺术
1.3.5 什么是整洁代码
1.4 思想流派
1.7 前传与原则
第2章 有意义的命名
2.1 介绍
2.2 名副事实上
2.4 做有意义的区分
2.6 使用可搜索的名称
2.7 避免使用编码
2.7.1 匈牙利语标记法
2.7.2 成员前缀
2.7.3 接口和实现
2.8 避免思维映射
类名与对象名应该是名词与名词短语。不能使动词。
2.12 每一个概念相应一个词
2.13 别用双关语
2.14 使用解决方式领域名称
2.15 使用源自所涉问题领域的名称
2.17 不要加入无用的语境
2.18 最后的话
取好名字最难的地方在于须要良好的描写叙述技巧和共同拥有文化背景。
第3章 函数
3.1 短小
3.2 仅仅做一件事
3.3 每一个函数一个抽象层级
3.4 switch语句
3.5 使用描写叙述性的名称
3.6.2 标识參数 - 假设须要向方法传入true或者false说明方法肯定要做两件事情
3.6.3 二元函数
3.6.4 三元函数
3.6.5 參数对象 - 假设參数过多,能够直接把这些參数封装到一个对象中
3.6.6 參数列表 - 即使是能够传入多个參数。可是超过3个还是要考虑下怎样精简
3.8 分隔指令与询问
3.9.2 错误处理就是一件事
3.9.3 Error.java依赖磁铁
3.10 别反复自己
3.11 结构化编程
3.12 怎样写出这种函数
3.13 小结
3.14 SetupTeardownIncluder程序
3.15 文献
第4章 凝视
4.1 凝视不能美化糟糕的代码
4.2 用代码来阐述
4.3 好凝视
4.3.1 法律信息
4.3.2 提供信息的凝视 - 在正則表達式上加入符合要求的样例。返回值的含义包括在函数名中。
4.3.3 对意图的解释 - 有些地方编写的代码可能跟常识不符合,可是是由于某种特定环境下必须这样写,能够用凝视解释下。
4.3.4 阐释
4.3.5 警示 - 对代码改动的注意事项等。
4.3.6 TODO凝视
4.3.7 放大
4.3.8 公共API中的Javadoc - 能够学习下javadoc
4.4 坏凝视
4.4.1 喃喃自语 - 有些凝视没解释清楚事情,好像是作者写给自己看的哑谜
4.4.3 误导性凝视 - 某种特别情况凝视中却没有描写叙述,可是使用函数却不是和凝视一样的效果。
4.4.4 循规式凝视 - 每一个变量名、每一个函数都有凝视反倒成了愚蠢可笑。
4.4.5 日志式凝视 - 加入谁改动了。可是如今SVN等代码管理工具能够查看了
4.4.6 废话凝视
4.4.7 可怕的废话
4.4.8 能用函数或变量时就别用凝视
4.4.9 位置标记 - 使用//// 把一些功能分开,书中不建议使用。可是我个人感觉这样能使代码清晰些。
4.4.10 括号后面的凝视 - 多层嵌套。在括号的结尾加入上属于哪个控制keyword的结尾括号。这样的情况能够抽取到多个方法中
4.4.11 归属与署名 - 不须要,由于有源码控制系统
4.4.12 凝视掉的代码 - 临时不须要的代码能够直接删除,不是必需凝视掉。能够使用源码控制系统找到之前版本号
4.4.13 HTML凝视
4.4.14 非本地信息
4.4.15 信息过多 - 主须要最核心信息,不是必需大段描写叙述
4.4.16 不明显的联系
4.4.17 函数头
4.4.18 非公共代码中的Javadoc - public须要加入javadoc告诉使用者一些信息,可是private方法非常多时候不须要
4.4.19 范例
第5章 格式
5.1 格式的目的
5.2 垂直格式
5.2.1 向报纸学习
5.2.2 概念间垂直方向上的区隔
5.2.5 垂直顺序
5.3 横向格式
5.3.1 水平方向上的区隔与靠近
5.3.2 水平对齐
5.3.3 缩进
5.5 鲍勃大叔的格式规则
第6章 对象和数据结构
6.1 数据抽象
6.2 数据、对象的反对称性
6.3 得墨忒耳律
6.3.1 火车失事
6.3.2 混杂
6.3.3 隐藏结构
6.4 数据传送对象
6.5 小结
对象暴露行为。隐藏数据。
第7章 错误处理
7.1 使用异常而非返回码
7.2 先写Try-Catch-Finally语句
7.5 依调用者须要定义异常类
7.6 定义常规流程
7.8 别传递null值
7.9 小结
7.10 文献
第8章 边界
8.1 使用第三方代码
8.2 浏览和学习边界
8.4 学习性測试的优点不仅仅是免费
8.5 使用尚不存在的代码
8.6 整洁的边界
8.7 文献
第9章 单元測试
9.1 TDD三定律
2. 仅仅有编写刚好无法通过的单元測试,不能编译也算不通过。
3. 仅仅可编写刚好足以通过当前失败測试的生产代码。
9.2 保持測试整洁
9.3 整洁的測试
9.3.1 面向特定领域的測试语言
9.3.2 双重标准
9.4 每一个測试一个断言
9.5 F.I.R.S.T.
独立(Independent):測试应相互独立。
可反复(Repeatable):測试应当可在不论什么环境中反复通过。
自足验证(Self-Validating):測试应该有布尔值输出。
及时(Timely)測试应及时编写。
9.6 小结
第10章 类
10.1 类的组织
10.2 类应该短小
10.2.1 单一权责原则
10.2.3 保持内聚性就会得到很多短小的类
10.3 为了改动而组织
第11章 系统
11.1 怎样建造一个城市
11.2 将系统的构造与使用分开
11.2.1 分解main
11.2.2 工厂
11.2.3 依赖注入
11.3 扩容
11.5 纯Java AOP框架
11.6 AspectJ的方面
11.7 測试驱动系统架构
11.8 优化决策
11.9 明智使用加入了可论证价值的标准
11.10 系统须要领域特定语言
11.11 小结
第12章 迭进
12.1 通过迭进设计达到整洁目的
12.3 简单设计规则2~4:重构
12.4 不可反复
12.5 表达力
12.6 尽可能少的类和方法
12.7 小结
第13章 并发编程
13.1 为什么要并发
13.2 挑战
13.3 并发防御原则
13.3.3 推论:使用数据复本
13.3.4 推论:线程应尽可能地独立
13.4 了解Java库
比如数据库连接盒固定尺寸读/写缓存等。
每个线程都拥有其它线程须要的资源,得不到其它线程拥有的资源。就无法终止。
因为竞争的原因。线程会持续尝试起步,但在非常长的时间内都无法如愿,甚至永远无法启动。
13.5 了解运行模型
*** 13.5.1 生产者-消费者模型
*** 13.5.2 读者-作者模型
*** 13.5.3 宴席哲学家
13.6 警惕同步方法之间的依赖
13.7 保持同步区域微小
13.8 非常难编写正确的关闭代码
13.9 測试线程代码
13.9.1 将伪失败看作可能的线程问题
13.9.2 先使非线程代码可工作
13.9.3 编写可插拔的线程代码
13.9.4 编写可调整的线程代码
13.9.5 执行多于处理器数量的线程
13.9.6 在不同平台上执行
13.9.7 装置试错代码
13.9.8 硬编码
13.9.9 自己主动化
13.10 小结
13.11 文献
第14章 逐步改进
14.1 Args的实现
14.2 Args:草稿
14.2.1 所以我暂停了
14.2.2 渐进
14.3 字符串參数
14.4 小结
第15章 JUnit内幕
15.1 JUnit框架
15.2 小结
第16章 重构SerialDate
16.1 首先,让它能工作
16.2 让它做对
16.3 小结
16.4 文献
第17章 味道与启示
C1.不恰当的凝视
让不恰当的凝视保存到源码控制系统。
C2.废弃的凝视
过时、无关或不对的凝视就是废弃的凝视不应该保留必须立即删除。
C3.冗余的凝视
凝视应该谈及代码自身没提到的东西。否则就是冗余的。
C4.糟糕的凝视
值得编写的凝视必须正确写出最好的凝视,假设不是就不要写。
C5.凝视掉的代码
凝视掉的代码必须删除。
环境
E1.须要多步才干实现的构建
构建系统应该是单步的小操作。
E2.须要多步才干实现的測试
仅仅须要单个指令就能够执行全部单元測试。
函数
F1.过多的參数
函数參数应该越少越好,坚决避免有3个參数 的函数。
F2.输出參数
输出參数违反直接,抵制输出參数。
F3.标识參数
布尔值參数令人迷惑,应该消灭掉。
F4.死函数
永不被调用函数应该删除掉。
一般性问题
G1.一个源文件存在多个语言
尽量降低源文件语言的数量和范围。
G2.明显的行为未被实现
遵循“最少惊异原则”,函数或者类应该实现其它程序猿有理由期待的行为,不要让其它程序猿看代码才清楚函数的作用。
G3.不对的边界行为
代码应该有正确的行为,追索每种边界条件并进行全面測试。
G4.忽视安全
关注可能引起问题的代码,注重安全与稳定。
G5.反复
消除反复代码,使用设计模式。
G6.在错误的抽象层级上的代码
抽象类和派生类概念模型必须完整分离,比如:与实现细节有关的代码不应该在基类中出现。
G7.基类依赖于派生类
基类应该对派生类一无所知。
G8.信息过多
类中的方法,变量越少越好,隐藏全部实现。公开接口越少越好。
G9.死代码
找到并删除全部不被调用的代码。
G10.垂直分隔
变量和函数的定义应该靠近被调用代码。
G11.前后不一致
函数參数变量应该从一而终,保持一致,让代码便于阅读和改动。
G12.混淆视听
无用的变量。不被调用的函数,没有信息量的凝视应该清理掉。
G13.人为耦合
不互相依赖的东西不该耦合。
G14.特性依恋
类的方法应该仅仅对自身的方法和变量感兴趣,不应该垂青其它类的方法和变量。
G15.选择算子參数
避免布尔类型參数。使用多态取代。
G16.晦涩的意图
代码要尽可能具有表达力,明确的意图比高效和性能重要。
G17.位置错误的权责
“最少惊异原则”,把代码放在读者想到的地方,而不是对自己方便的地方。
G18.不恰当的静态方法
假设要使用静态方法,必须确保没机会打算让它有多态行为。
G19.使用解释性变量
把计算过程打散成一系列命名良好的中间值使程序更加可读性。
G20.函数名称应该表达其行为 G21.理解算法
G22.把逻辑依赖改为物理依赖
依赖应该是明显而不应该是如果的依赖。
G23.用多态替代If/Else或Switch/Case G24.遵循标准约定 G25.用命名常量替代魔术数 G26.准确
代码中的含糊和不准确要么是意见不同的结果,要么源于懒散,都必须消除。
G27.结构甚于约定 G28.封装条件
把条件封装成方法。
G29.避免否定性条件
使用肯定性条件。
G30.函数仅仅该做一件事 G31.掩蔽时序耦合
创建顺序队列暴露时序耦合,每一个函数都产生一下函数所需參数,就可保障正确的时序。
G32.别任意
代码不能任意。须要慎重考虑。
G33.封装边界条件
比如:+1或-1操作必须封装起来。
G34.函数应该仅仅在一个抽象层级上
封装不在一个抽象层级上的代码,保持每一个函数仅仅在一个抽象层级上。
G35.在较高层级放置可配置数据
把配置数据和常量放到基类里。
G36.避免传递浏览
“得墨忒耳律”,编写害羞代码。让直接协作者提供所需的服务。而不要逛遍整个系统。
JAVA
J1.通过使用通配符避免过长的导入清单 J2.不要继承常量 J3.常量VS.枚举
使用枚举enum取代常量。
名称
N1.採用描写叙述性名称
名称相应可读性有90%的作用,必须认真命名。
N2.名称应与抽象层级相符
不要取沟通实现的名称:取反映类或函数抽象层级的名称。
N3.尽可能使用标准命名法 N4.无歧义的名称
N5.为较大作用范围选用较长名称 N6.避免编码
不应该在名称中包括类型或范围的信息,比如:m_,f等前缀。
N7.名称应该说明副作用
名称应该说明类、变量或函数的全部信息,不应该隐藏副作用。
測试 T1.測试不足
保证足够的測试。
T2.使用覆盖率工具
覆盖率工具能够更好地找到測试不足的模块、类、函数。
T3.别略过小測试
T4.被忽略的測试就是对不确定事物的疑问
用@Ignore表达我们对需求的疑问。
T5.測试边界条件
边界判读错误非经常见。必须測试边界条件。
T6.全面測试相近的缺陷
缺陷趋向于扎堆,假设在函数中发现一个缺陷。那么就全面測试这个函数。
T7.測试失败的模式有启示性
你能够通过測试失败找到问题所在。
T8.測试覆盖率的模式有启示性
通过測试覆盖率检查,往往能够找到測试失败的线索。
T9.測试应该高速
慢測试会导致时间紧时会跳过,导致可能出现故障。