什么是重构
重构是一个系统化的过程,在不创建新功能的情况下改进代码,从而将混乱的代码转化为干净的代码和简单的设计,其主要目的是减少技术债务。
干净的代码
什么是干净的代码?它有以下几个特点:
-
干净的代码对于其他程序员来说是显而易见的
不是说超复杂的算法,糟糕的变量命名,臃肿的类和方法,神奇的数字,所有这些都让代码变得草率而难以理解。
-
干净的代码不包含重复
每次必须对重复代码进行更改时,都必须记住对每个实例进行相同的更改。这会增加认知负荷,减缓进度。
-
干净的代码包含最少数量的类和其他活动部件
代码越少,你脑子里的东西就越少。更少的代码意味着更少的维护。代码越少,错误越少。代码就是责任,保持简短。
-
干净的代码通过了所有测试
当只有95%的测试通过时,你知道你的代码是脏的。你知道当你测试覆盖率为0%时,你就完蛋了。
-
干净的代码更容易维护,成本更低!
技术债务
每个人都尽最大努力从头开始编写优秀的代码。可能没有一个程序员故意编写不干净的代码,而损害了项目。但是,在什么时候,干净的代码会变得不干净?
关于不干净代码的“技术债务”的隐喻最初是由沃德·坎宁安提出的。
如果您从银行获得贷款,这允许您更快地进行购买。您为加快流程支付额外费用——您不仅还清了本金,还支付了贷款的额外利息。不用说,你甚至可以积累如此多的利息,以至于利息金额超过你的总收入,使全额还款变得不可能。
代码也会发生同样的事情。您可以在不编写新功能测试的情况下暂时加快速度,但这会逐渐减慢您每天的进度,直到您最终通过编写测试还清债务。
产生的原因
商业压力
有时,商业环境可能会迫使您在功能完全完成之前推出这些功能。在这种情况下,补丁和污点将出现在代码中,以隐藏项目未完成的部分。
对技术债务的后果缺乏了解
有时,您的雇主可能不明白技术债务具有“利益”,因为它随着债务的积累而减缓了发展速度。这可能会使团队花时间重构变得太困难,因为管理层看不到它的价值。
未能对抗组件的严格一致性
这是当项目类似于整体而不是单个模块的乘积时。在这种情况下,对项目一部分的任何更改都会影响其他部分。团队发展变得更加困难,因为很难孤立单个成员的工作。
缺乏测试
缺乏即时反馈会鼓励快速但有风险的变通办法或揉捏造。在最坏的情况下,这些更改在没有任何事先测试的情况下直接实施并部署到生产中。后果可能是灾难性的。例如,一个看起来很无辜的修复程序可能会向数千名客户发送一封奇怪的测试电子邮件,甚至更糟糕的是,冲洗或损坏整个数据库。
缺乏文档
这减缓了新人引入项目的速度,如果关键人物离开项目,可能会使开发陷入停顿。
团队成员之间缺乏互动
如果知识库没有分布在整个公司,人们最终会对项目流程和信息有过时的理解。当初级开发人员被他们的导师错误地培训时,这种情况可能会加剧。
几个分支的长期同时发展
这可能导致技术债务的积累,然后在合并变化时增加技术债务。孤立地发生的变化越多,技术债务总额就越大。
延迟重构
该项目的要求在不断变化,在某个时候,代码的某些部分可能已经过时,变得繁琐,必须重新设计以满足新的要求。
另一方面,该项目的程序员每天都在编写适用于过时部分的新代码。因此,重构延迟的时间越长,将来就越依赖代码。
缺乏合规性监测
当每个从事项目工作的每个人都按照他们认为合适的方式编写代码时(即与他们编写上一个项目的方式相同),就会发生这种情况。
无能
这是开发人员不知道如何编写像样的代码的时候。
何时重构
三条规则
-
当你第一次做某事时,就把它做完。
-
当你第二次做类似的事情时,对不得不重复而畏缩,但无论如何都要做同样的事情。
-
当你第三次做某事时,开始重构。
添加功能时
- 重构可帮助您理解他人的代码。如果您必须处理其他人的脏代码,请先尝试重构它。干净的代码更容易掌握。你不仅会为自己,还会为你之后使用它的人改进它。
- 重构可以更轻松地添加新功能。更改干净的代码要容易得多。
修复错误时
代码中的错误的行为与现实生活中的错误一样:它们生活在代码中最黑暗、最肮脏的地方。清理你的代码,错误实际上会发现自己。
经理们非常重视主动重构,因为它消除了以后对特殊重构任务的需求。快乐的老板让程序员快乐!
在代码审查期间
代码审查可能是在向公众开放之前整理代码的最后机会。
最好与作者成对进行这样的评论。这样,您可以快速解决简单的问题,并衡量解决更困难的问题的时间。
如何重构
重构应作为一系列小更改进行,每个更改都使现有代码稍微好一点,同时使程序保持工作状态。
代码应该变得更干净。
如果代码在重构后仍然不干净…好吧,我很抱歉,但你刚刚浪费了生命中的一个小时。试着弄清楚为什么会发生这种情况。
当您从小更改中摆脱重构,并将一大堆重构混合到一个大更改中时,这种情况经常发生。所以很容易失去理智,特别是如果你有时间限制的话。
但在处理非常草率的代码时,也可能发生这种情况。无论你改进了什么,整个代码仍然是一场灾难。
在这种情况下,值得考虑完全重写代码的部分内容。但在此之前,你应该进行笔试,并留出大量时间。否则,你最终会得到我们在第一段中讨论的结果。
重构期间不应创建新功能。
不要将重构和直接开发新功能混为一谈。尝试至少在单个提交范围内分离这些进程。
所有现有测试必须在重构后通过。
在重构后,测试可能会崩溃,有两种情况:
-
**您在重构过程中出错。**这个是轻而易举的:继续修复错误。
-
**你的测试水平太低了。**例如,您正在测试类的私有方法。
在这种情况下,测试是罪魁祸首。您可以自己重构测试,也可以编写一套全新的高级测试。避免这种情况的一个好方法是编写BDD风格的测试。
评论区