前言
在不久的过去,我在知乎看到这样一句话:「 驾驭屎山的唯一方法,不是重构,而是 不重构 」 。
我觉得说的很有道理。但并没有将它当作准则,还是进行了整个项目完全重构的操作。
重构
重构起因
最终我还是决定重构,重构的原因基于以下几个方面。
原因有四:
- 领导的支持,愿意为此付出成本,且付出时间
- 该项目由 项目A 完全
copy
至 项目B ,且 项目B 只用到了 项目A 中1/4
的功能 - 该项目与其他项目使用 技术栈 差异过大,导致无法统一相同类型项目的 项目架构
- 该项目在
新增/修改
功能时,由于代码过于古老,导致十分痛苦
重构过程
其实准确的说并不应该说是重构「屎山」,更像是重写「屎山」。
- 将需要的页面整理,拆解成一个个任务。
- 将整个项目底层重新搭建,摒弃未引入的库,重写了路由、请求封装、utils工具、文件结构、代理、 ....
- 将一个个页面通过新框架重写
重构上线
待到整个项目重构完成,上线时。出问题了 emmm.... 问题列表:
- 有一个已经被引用的页面未整理到,导致该页面无了
- 有一个页面
title
写了个错别字(续 写成了 绪) - 有一个页面的数据请求接口,应该是
GET
,且我也发送了GET
请求,但旧代码请求类型是POST
导致接口请求失败 PS:在 问题3 出现之前,我就遇到了本该是POST
的接口请求类型是GET
的问题。但万万没想到GET
类型会出现POST
接口请求。
遇到 问题1 时,我尽快将页面加上
遇到 问题2 时,抓紧调整错别字
遇到 问题3 时,我抓紧改掉了
但出了这么多问题,如果有更严重的问题系统是无法接受的,我果断回滚了代码
我现在便卡在了这里,问题都解决了但不敢上线了,因为 问题3 的页面我实际上在测试环境请求过很多次,没有出现该问题。我担心会有其他未测出的 bug。
我对问题本身并不关心,最关心的是为什么出现了问题后,我不敢上线了。
最后总结出以下几条:
- 领导希望的是项目不出现任何问题的情况下 无缝切换
- 产品已经在线上 平稳运行 ,如果重构出现任何问题,都难以接受
- 相较于新产品而言,用户对
bug
的乍现容忍度更低 - 没有测试
- 没有分步上线,进而导致问题的集中爆发
总结
为了保证我们的重构 没有惊喜 的完成,我们需要清楚以下问题:
- 是否需要重构?
- 为什么要重构?
- 应该如何重构?
是否需要重构
如果早明白这个道理,我一定不会贸然重构!!
if (项目过于庞大) {
return 千万不要重构!!
}
if (大块的代码你搞不明白是做什么用的) {
return 千万不要重构!!
}
if (你在该公司待不到 1 年) {
return 不需要重构
}
if (你们需要为 KPI 服务 && 重构对 KPI 无益) {
return 不需要重构
}
if (你的领导不希望你重构) {
return 不需要重构
}
return 你大概率不需要重构
大多数情况下,普通开发者不要考虑重构的问题。
当你在考虑重构问题时,你应该慎重考虑以下几方面:
- 对公司是否有益
- 大多数情况下,重构对公司的益处都是不大的,因为难以保证由 「屎山1.0」 进步成 「屎山2.0」
- 对自身是否有益
- 大多数情况下,重构所带来的收益远远不如拿出该时间 学习新知识 、 巩固旧知识
- 成本和收益是否成正比
- 大多数情况下,重构的成本和收益是不成正比的
- 如何保证后续的效果
- 提前指定规范,并保证 重构过程中 + 后续维护中 严格遵守规范中的规定
为什么要重构
当一个系统在线上稳步运行时,重构总需要有充分的理由,这个理由不能是 "为了扩展性、维护性"
,大规模重构消耗掉的资源不是短短这么两个短句就可以支撑的。
你至少要保证对以下几点中的一点严重不足时,才考虑这件事:
- 性能不足
- 现有的代码不能在线上平稳运行,不能保证用户的体验
- 扩展能力
- 现有的代码基本无法扩展,在新需求来临时,难以完成
- 维护成本
- 现有代码在维护上有致命的缺陷,导致你们团队对重构的需求激增
否则:
- 在重构前,其他人无法准确预估你的工作量
- 在重构时,其他人在出现问题后没办法接受
- 在重构后,其他人察觉不到重构带来的好处 且:
- KPI 玩完
应该如何重构
在重构一个已经在 平稳运行 的项目,我们不能将一段时间完全留给重构,重构应该和 业务需求 平步进行,且 业务需求 在前,研发需求 在后。
我们重构至少遵循以下原则:
在重构前,保证项目兼容性、保证对代码的充分理解、保证对任务的拆分、保证规范的确立;
在重构中,保证不影响 业务需求 开发、保证分步上线;
在重构后,保证测试完整覆盖、保证严格按照规范进行维护。
这些都是为了我们的重构过程中不出现 惊喜 ,这里的 惊喜 是中性词,你的重构过程中不应该出现任何 惊喜 ,无论好坏。
重构前
在项目重构前,我们必须:
- 为了保证项目重构后的 兼容性 进行调研
- 为了保证项目重构后的 稳步运行 进行深度代码阅读
- 为了保证项目时效,对 重构时间 进行准确的预估
- 对重构的上线过程模块规模细化,避免一次上线模块过多、过少
- 制定好重构后的项目的 编码规范
- 准备好 新域名、新仓库 ,方便项目分步上线
重构中
在项目重构中,我们必须:
- 保证重构前后页面的一致性、功能的一致性
- 合理安排好时间,保证不影响业务需求开发
- 做好单元测试
- 分步上线
- 做好线上测试
重构后
在项目重构后,我们必须:
- 保证测试的完整覆盖,避免出现未测试的代码,出现令人惊喜的
bug
- 针对制定好的 规范 进行项目的维护,避免从 「屎山1.0」 进步成 「屎山2.0」
总结
本次重构出现的问题算是比较经典的问题,代表了在重构整个项目的生命周期中出现的典型问题。
问题1:不必要的重构
本次重构说到底还是一次不必要的重构,重构的结局是没有收获任何好处,反而得到了一堆问题。
隐性的好处是:
- 在后续的更新中,可以统一的抽离出同一场景下用到的相同内容至
npm
- 在新的前端同学入职后,可以更快的上手这一场景下的所有项目
问题2:采用全部写完一次性上线的方式进行
全部写完一次性上线的好处是:
- 不需要一个新的域名、新的仓库进行中间替换 缺点是:
- 导致每个模块的测试不够细致,从而忽略掉了部分问题
- 导致问题大规模爆发,从而导致情绪波动,从而引发连锁反应
问题3:模块缺失
对已用模块收集不够细致,从而导致上线时模块缺失
问题4:页面了解不够
由于对页面了解不够深入,导致测试时,漏掉部分后台入口,从而导致问题的发生。