第一部分 修改机理第1章 修改软件 1.1 修改软件的四个起因 1.1.1 添加特性和修正bug 1.1.2 改善设计 1.1.3 优化 1.1.4 综合起来 1.2 危险的修改第2章 带着反馈工作 2.1 什么是单元测试 2.2 高层测试 2.3 测试覆盖 2.4 遗留代码修改算法 2.4.1 确定修改点 2.4.2 找出测试点 2.4.3 解依赖 2.4.4 编写测试 2.4.5 改动和重构 2.4.6 其他内容第3章 感知和分离 3.1 伪装成合作者 3.1.1 伪对象 3.1.2 伪对象的两面性 3.1.3 伪对象手法的核心理念 3.1.4 仿对象第4章 接缝模型 4.1 一大段文本 4.2 接缝 4.3 接缝类型 4.3.1 预处理期接缝 4.3.2 连接期接缝 4.3.3 对象接缝第5章 工具 5.1 自动化重构工具 5.2 仿对象 5.3 单元测试用具 5.3.1 JUnit 5.3.2 CppUnitLite 5.3.3 NUnit 5.3.4 其他xUnit框架 5.4 一般测试用具 5.4.1 集成测试框架 5.4.2 Fitnesse第二部分 修改代码的技术第6章 时间紧迫,但必须修改 6.1 新生方法 6.2 新生类 6.3 外覆方法 6.4 外覆类 6.5 小结第7章 漫长的修改 7.1 理解代码 7.2 时滞 7.3 解依赖 7.4 小结第8章 添加特性 8.1 测试驱动开发 8.1.1 编写一个失败测试用例 8.1.2 让它通过编译 8.1.3 让测试通过 8.1.4 消除重复 8.1.5 编写一个失败测试用例 8.1.6 让它通过编译 8.1.7 让测试通过 8.1.8 消除重复代码 8.1.9 编写一个失败测试用例 8.1.10 让它通过编译 8.1.11 让测试通过 8.1.12 消除重复 8.2 差异式编程 8.3 小结第9章 无法将类放入测试用具中 9.1 令人恼火的参数 9.2 隐藏依赖 9.3 构造块 9.4 恼人的全局依赖 9.5 可怕的包含依赖 9.6 “洋葱”参数 9.7 化名参数第10章 无法在测试用具中运行方法 10.1 隐藏的方法 10.2 “有益的”语言特性 10.3 无法探知的副作用第11章 修改时应当测试哪些方法 11.1 推测代码修改所产生的影响 11.2 前向推测 11.3 影响的传播 11.4 进行影响推测的工具 11.5 从影响分析当中学习 11.6 简化影响结构示意图第12章 在同一地进行多处修改,是否应该将相关的所有类都解依赖 12.1 拦截点 12.1.1 简单的情形 12.1.2 高层拦截点 12.2 通过汇点来判断设计的好坏 12.3 汇点的陷阱第13章 修改时应该怎样写测试 13.1 特征测试 13.2 刻画类 13.3 目标测试 13.4 编写特征测试的启发式方法第14章 棘手的库依赖问题第15章 到处都是API调用第16章 对代码的理解不足 16.1 注记/草图 16.2 清单标注 16.2.1 职责分离 16.2.2 理解方法结构 16.2.3 方法提取 16.2.4 理解你的修改产生的影响 16.3 草稿式重构 16.4 删除不用的代码第17章 应用毫无结构可言 17.1 讲述系统的故事 17.2 Naked CRC 17.3 反省你们的交流或讨论第18章 测试代码碍手碍脚 18.1 类命名约定 18.2 测试代码放在哪儿第19章 对非面向对象的项目,如何安全地对它进行修改 19.1 一个简单的案例 19.2 一个棘手的案例 19.3 添加新行为 19.4 利用面向对象的优势 19.5 一切都是面向对象第20章 处理大类 20.1 职责识别 20.2 其他技术 20.3 继续前进 20.3.1 战略 20.3.2 战术 20.4 类提取之后第21章 需要修改大量相同的代码第22章 要修改一个巨型方法,却没法为它编写测试 22.1 巨型方法的种类 22.1.1 项目列表式方法 22.1.2 锯齿状方法 22.2 利用自动重构支持来对付巨型方法 22.3 手动重构的挑战 22.3.1 引入感知变量 22.3.2 只提取你所了解的 22.3.3 依赖收集 22.3.4 分解出方法对象 22.4 策略 22.4.1 主干提取 22.4.2 序列发现 22.4.3 优先提取到当前类中 22.4.4 小块提取 22.4.5 时刻准备重新提取第23章 降低修改的风险 23.1 超感编辑 23.2 单一目标的编辑 23.3 签名保持 23.4 依靠编译器第24章 当你感到绝望时第三部分 解依赖技术第25章 解依赖技术 25.1 参数适配 25.2 分解出方法对象 25.3 定义补全 25.4 封装全局引用 25.5 暴露静态方法 25.6 提取并重写调用 25.7 提取并重写工厂方法 25.8 提取并重写获取方法 25.9 实现提取 25.9.1 步骤 25.9.2 一个更复杂的例子 25.10 接口提取 25.11 引入实例委托 25.12 引入静态设置方法 25.13 连接替换 25.14 参数化构造函数 25.15 数化方法 25.16 朴素化参数 25.17 特性提升 25.18 依赖下推 25.19 换函数为函数指针 25.20 以获取方法替换全局引用 25.21 子类化并重写方法 25.22 替换实例变量 25.23 模板重定义 25.24 文本重定义附录重构术语表索引