# 项目总结

重构不应改变软件外在的可观察行为，但通过优化软件的内部结构，我们提高了代码的可维护性，实际上是有效地降低了出 bug 的概率。此外，实施重构的另一个好时机是在添加新特性之前：通过对现有代码进行目标明确的重构，往往可以使得新特性的添加更加简单。

刚拿到 BugsZero 的代码时，我们看到的是一个很大的`Game`类，里面包含了所有的代码，充斥着各种各样的细节，比如问题的初始化、玩家数据数组的初始化与更新等等。为了理解程序如何运行，我们不得不阅读全部的代码；为了添加一些新的特性，我们更是得通读所有代码，并在多处地方做出修改；如果不仔细阅读，我们甚至很难察觉到程序里面还有 bug 的存在……

面对这样的情况，我们可以尝试在测试的保护下做些适当的重构：先做些简单的清理（类型声明、重命名等），再消除一些明显的坏味道（重复代码、依恋情结等），以此作为我们开始的起点。之后，我们再观察，新特性的添加是否简单，如果不是，下一个重构的目标应该是使这个特性变得更加简单，更不容易出错。如此一来，我们既能控制重构的规模，又能提供高质量的特性交付。

在这个清理的过程中，我们做了这些练习：

* 巩固了先对代码做简单清理的习惯
* 通过“提炼函数”消除了简单的重复代码
* 通过“提炼变量”消除了耦合的硬编码
* 通过“以对象取代基本类型”创建了领域对象，消除了“基本类型偏执”坏味道
* 通过“搬移字段”“搬移函数”等手法消除了“依恋情结”“发散式变化”坏味道
* 体会了代码结构随着重构浮现的节奏感

在重构过程中，我们仍然保持小步前进的优良传统，这样出错时可以很快地回滚代码到上一个可工作的状态。并且，我们带着明确的目标来开展重构工作：要么是为了消除一个明显的坏味道，要么是为了让新特性的添加变得简单。有了这个节奏，加上小步前进带来的随时停止的能力，我们就可以有条不紊地把握重构的起止，在“添加新特性”和“重构”这两顶帽子间随时切换。这样既不会耽误新特性的开发，又可以一步步地慢慢清理旧代码，让代码库越来越好。
