科技壹零扒|再读《重构》

新版本以JavaScript语言作为示例 , 重新思考并改进了第一版本中的众多重构手法 , 结合作者多年来一些新的观点和思考 , 带给了我们一套更为丰富完善的重构体系 。
重构作为敏捷实践的精髓之一 , 在我们这个以敏捷为立身之本的公司里应当属于大家信手拈来的基本技能 。 虽说其基本思想长期不过时 , 但是第一版《重构》的发布毕竟已经是20年前的事情了 , 这期间软件开发行业兴起了无数新的编程思想、语言、工具、框架等 , 现在回过头去看第一版 , 会发现不仅纸质书籍难以买到 , 其中的一些知识上也有点脱节 。 新版本以JavaScript语言作为示例 , 重新思考并改进了第一版本中的众多重构手法 , 结合作者多年来一些新的观点和思考 , 带给了我们一套更为丰富完善的重构体系 。
通读本书 , 很多地方都让我产生共鸣 , 同时也让我对于日常的一些实践有了新的看法 , 并在一些问题上有了新的结论 。 下面想摘录一些重要的观点 , 并分享我的理解 , 与大家一起学习 。
科技壹零扒|再读《重构》
文章图片
《重构》
重构的几个要点
书中讲到的几个重构要点值得每个人在实践重构的时候注意:
重构不应改变原有程序的可观测的行为把添加新功能和重构当做两件不同的事情来对待 , 就像两顶帽子 , 在开发过程中我们经常两顶帽子换着戴小步重构 , 更安全的前进 , 让代码在绝大部分时间处于可工作的状态捡垃圾式的重构:发现一个垃圾时 , 不想跑题太多 , 同时也不想将垃圾留在原地;如果此时很容易重构 , 就立即完成 , 否则就记录下来 , 等后续再来重构绝大多数的重构是见机行事的 , 而非单独安排的一项工作重构的唯一目的是让我们开发更快 , 用更少的工作量创造更高的价值;重构不是来自“整洁的代码”“良好的工程实践”等道德要求 , 而是纯粹从经济角度出发的考量自测试代码是重构的基石 , 也是持续集成的关键环节 。 要想“敏捷”做到名副其实 , 必须要做好这三大实践–自测试代码、持续集成、重构(自测试代码和重构一起构成了TDD)各种基础重构手法组合使用 , 以实现高级的重构目的
我常常见到团队中有人在得到一个好的设计之后 , 就完全忽略之前的代码 , 重新进行一遍实现 。 然而重新实现一遍代码真的不难 , 难点在于如何让之前的遗留代码还能正常工作 。 我们常常要手工去处理这些遗留代码 , 不仅非常花费时间 , 还很容易出错 , 如果之前的代码自动化测试不足 , 那基本上等于自己给自己挖了一个大坑 。 有时 , 我们还可能会让代码中存在两个版本的逻辑 , 给新的API一个版本号 , 这就更让人疑惑了 。 试想 , 如果我们在修改已有的代码 , 我们是否应该用新的API呢?新的API真的能和已有的老版本API兼容吗(常常是不行的 , 比如我们可能会将数据写入到两个不同的数据库表)?
老马在书中反复地乐此不疲地强调小步重构 , 以便可以随时回退到上一个可工作的版本再次来过 。 我能想象在没有重构工具支撑时 , 这是多么重要 。 但是 , 现在我们的自动化重构工具已经比较成熟(特别是静态类型语言) , 我们在做重构时 , 常常以较大的步子快速完成 , 我自己也经常这么做 。 这使得当我们要做一个巨大的重构的时候 , 常常忘了通过小步重构来实现 。 上文提到的的不计后果的重写某个模块就是这样的一个例子 。
科技壹零扒|再读《重构》
文章图片
实际上通过一系列的小步重构 , 我们几乎可以完成任意的巨大重构 。 比如书中的例子 , 以子类取代类型码的重构 。 这是一个很复杂的重构了 , 但是我们可以通过这样一系列步骤安全的进行:
用封装变量将类型码封装到一个函数内部创建一个工厂函数 , 根据类型构造不同的子类创建其中一个子类在工厂函数中替换构造出来的对象对每个类型重复上述操作去除类型码使用函数下移重构和以多态处理条件表达式重构来处理原来的函数调用处的代码【科技壹零扒|再读《重构》】营地法则


推荐阅读