Skip to content

重构

一般程序员写得出计算机能读懂的代码。优秀程序员写得出人能读懂的代码。

什么是重构

重构是一系列小修改,改进软件结构,在每次修改后通过一套完整测试集,以此证明没有改动软件的行为。

首先,重构不改变软件的行为。其次,每次重构都很小,小到不需要调试的程度。

重构的目的是清理代码。重构是一种持续行为,而非有计划地安排的行为。

基础工具包

有几个重构的手段。

重命名

给某件事物命名,往往是个连续、迭代的改进过程。请频繁地重命名类和方法。只要这么做,你就会发现,应该以不同方式组织这些类和代码。为了与新名称保持一致,你会把方法从一个类迁移到另一个类。为了符合新的命名模式,你会重新划分函数和类。

在将代码切分为类和模块时,找寻最好名称有可能给你的设计带来很积极的影响。

方法抽取

方法抽取可能是所有重构手段中最重要的那个。这种重构手段是保持代码整洁和有效组织的最重要机制。

方法抽取遵循⌈抽取到底⌋原则,即不断地抽取。首先,每个函数只做一件事。其次,代码读起来得像是篇好文章。

如果不能从函数中抽取出其他函数,那么这个函数制作一件事。

函数名称的长度与其涵盖范围应该成反比。公有函数的名称应相对短,私有函数的名称应更长一些。

抽取出来的函数,大多数只会在一个地方被调用,所以其目标也会极特殊和极精准。

变量抽取

变量抽取是重构的辅助手段。

变量抽取的另一常见用途是创建解释性变量,如将 if 中的判断抽取出为布尔值。

纪律

重构也必须按规矩做事。

测试

重构的基础是测试,我们需要可信的测试集。

快速测试

测试也需要快。如果测试得花上几小时(或只是几分钟)运行,重构就不会顺利。如果测试集过大,做对应的子测试。

打破紧密的一一对应关系

上一章说到,测试与代码之间的联系过于紧密会导致脆弱测试。为了防止脆弱测试的出现,我们要打破紧密的一一对应关系。

持续重构

边写代码边测试。始终记得重构循环,每隔几分钟就来一次。

果断重构

重构时要勇敢。

让测试始终能通过

千万不要破坏测试!或者说,每次测试被破坏的时间不能超过几分钟。

如果重构需要几小时甚至几天来完成,那就将重构划分成小块,一边持续推进,一边保持测试通过。

如果需要修改系统的基础数据结构,应该另外创建一套新的数据结构,镜像旧数据结构的内容。然后,逐步将旧数据结构中的代码一点点移到新数据结构中,同时一直保持测试通过。

留条出路

万一重构失败,可以 git reset --hard。在开始一系列重构时,确保在仓库代码中打好标签,以便在需要时能够回滚。

小结

重构的最佳做法乃是掌握一套合用且常用的重构手段,同时熟知其他重构手段。

无测试则重构无意义。没有测试,出错机会太多。始终用完整测试集来保证重构顺利。

Released under the MIT License.