数量: 代码的行数
质量: 代码复杂度,耦合度,可读性,架构依赖复杂度等
成本: 花费的时间
回报 (成果): 支持后续功能的快速叠加,解决现有因代码设计问题无法优化的矛盾等
抓重点 抓重点啦
说了这么多废话,其实大家都明白没有与实践结合的理论都是空虚的.
但是 重构和 设计模式一样,也是需要一个 "学习——领悟——突破" 的过程.第一步的学习让你了解基本的重构手法,第二步的实践勾起你对重构手法的回忆以及重温应用,第三步的应用以及实践经验激发你的思考,领悟以及总结,以致于灵活运用.
但凡是人,总是在不断学习,不断温习,以达到具体场景具体应用,灵活自如. 重构是一个很大的话题,《重构》作者本人也是经历了 N 多的项目,以及多年的经验才总结出来的重构技巧.
重构技巧
《重构》一书作者总结的重构手法实在是太多了,只能通过图片来展示一下所有作者总结的重构列表.
具体的补充,大家可以看看 《重构》 一书.
重构的实践
作者推荐的一种做法:
随机挑选一个目标
先给自己选择一个目标 (譬如" 去掉一堆不必要的子类 "), 然后朝着目标前进,每一步走得小而坚定
没把握就停下来
当你无法证明自己所做的一切能够保证原有程序的逻辑和语义时,请你停下来思考:既有的重构是改善了还是毫无成果需要撤销.
保证每次重构后的测试都能正常跑通
作为开发者, 应当把重构作为开发的一部分,一边开发一边重构.在快速堆叠代码,实现基本需求功能的基础上,写好测试用例,保证功能不变,逐步重构.
这也是我们团队要求每个人都掌握重构这门必备技能的原因.优秀的程序员应当尽量避免低质量的代码.
重构案例
故事场景
有三种类型的电影,顾客可以进行租赁
租赁规则
价格计算规则:
普通片儿 —— 起步价 2¥,超过 2 天的部分每天每部电影收费 1.3 元
新片儿 —— 每天每部 3 元
儿童片 —— 起步价 2¥,超过 3 天的部分每天每部电影收费 0.8 元
积分计算规则:
每借一部电影积分加 1,新片每部加 2
原始代码
CODEPEN
程序结果:(请保证重构后结果不变~)
类图
有兴趣的可以先看看原始代码,考虑一下其中的原始对象关系,再行考虑如何重构代码. 原始代码其实是有很多问题可以挖掘的,下面是我们的讨论整理:
划分职责关系,遵循 单一职责原则
statement 打印账单函数承担了很多功能,包括收费计算,积分计算以及结果展示等等
解法 1: 6.1 Extract Method(提炼函数) —— 最常用的重构手法
解法 2: 9.1 Decompose Conditional(分解条件表达式)
用户类中承担了不属于它的职责,包括:收费规则,积分规则.这些职责应该是属于电影类型的.
整理清楚其中的业务逻辑,比如收费规则和积分规则 - 见故事场景
不要直接访问对象的数据.容易发生其他对象改变该对象的数据,而拥有该数据的对象却一无所知.
解法:8.10 Encapsulate Field(封装字段手法) —— 使数据和行为想分离
重构不应该被外界所感知,保证 testcases 依然可行
部分重构
这里为了更好的展示重构的手法,使用 TS,根据上面的讨论进行了部分重构,重构的方式其实是根据业务未来的扩展方向而定,并没有最优解,有兴趣的可以加入我们,抛出你的见解~
CODEPEN 执行结果:
重构后的类图关系
基本技巧
小步前进,频繁测试 (保证足够的测试来支持你的重构行动)
使用智能开发工具(比如 VSCode 右键可以将过长的函数代码拆解函数化)
推荐书籍
《代码整洁之道》
《重构 - 改善既有代码的设计》
《修改代码的艺术》
《代码大全》
重构其实是一件需要长期投入,并且投入产出比很高的事情.对重构感兴趣的同学可以关注专栏或者发送简历至'tao.qit####alibaba-inc.com'.replace('####', '@'),欢迎有志之士加入~
来源: https://juejin.im/post/5a5b2a5c6fb9a01cbc6e59f9