在三年前我就读了《重构改善既有代码的设计》,里面写了很多有关代码重构的技巧,知易行难!我整理了一下重构给我的感悟。
NO.1是什么导致的重构?
为业务的改变而调整
这是一个最合理的原因,我们无法预料到业务的发展,我们当下制定的业务职责和边界,对于一个快速发展的项目,能应对半年的情况,已经是一件相当不容易的事情。正如我们业务发展开始的时候,能承受起几千个用户。而当有十几万用户的时候,系统承受的压力是远远的不一样的。
为自己or别人的错误埋单!
代码是由程序员创造,我们如果不好好教育代码,一旦让它成为令人抓狂的“熊孩子”,最终的恶果还是我们自己承受。我也会吐槽自己写过的代码,毕竟编程技巧是一项技艺,需要日复一日的不断磨练,需要承受自己给自己带来的坑,才会学会成长。作为一名及格的程序员不能把重构时刻挂在嘴边,正如教育孩子更多是需要言传身教,以身作则。所以我们要将重构彻底融入到每一句代码中,我们既是在不断写新的业务,也是不断在重构我们的代码。
“无奈”的架构师
很多公司招了一个牛逼的架构师,怎么可以在短时间内向公司证明自己的能力?重构无疑是一条快捷的出路。
因为公司之前的架构已经不能适应公司发展,导致了公司业务发展不顺。听说过有些创业公司,每招来一个架构师,就把之前的代码进行重构一次的事例。但是这种重构,更多的是重写,而不是重构。但这种重写,往往由于架构师对业务缺乏深度的认识和充裕的时间,带来了断崖般的崩塌,因为在重写的过程中,bug层出不穷,导致业务极其不稳定。这也是一些人对重构嗤之以鼻的情况的根源。
NO.2重构前提条件是什么?
全盘熟悉代码,掌控业务。
接手别人的项目时,在看到混乱不堪的代码后,不要一上来就开始大动干戈。先熟悉代码架构,如果一个代码架构都混乱不堪,那就多费点劲,将代码好好得梳理一遍,如果有详细地文档的话,配合文档一起阅读的效果会更好。但是现实却是,你不得不去阅读一些令你感到莫名其妙的代码,然后自己去整理文档。慢慢熟悉一个项目的业务逻辑,梳理清楚业务内部之间的关系。如果你不熟悉业务,不熟悉代码,来讲重构,无疑是重写的罢了。
时间!
在你尚没能熟练《重构》的各项技巧之前,请首先明白你当下是否有充足的时间,毕竟高效完成工作才是最重要的。在工作中,其他人更多只会关心的是程序员的产出:项目的稳定快速迭代,但是熟练技巧需要大量的练习时间。而大型的重构,则需要更加多的人力物力的投入。
NO.4重构的目标是什么?
标准化
在不断地编码过程中,遇到的重复的问题会越来越多,而各类语言框架正是将标准化的一种体现。而对遇到的重复问题进行标准化处理,除了能让我们避免重复劳动提高开发效率,及让我们将一些业务进行层次分工。在标准化的过程中,主要做的是将业务职责划分清楚,避免混乱不堪的界面。
标准化是一个很漫长的过程,收益很明显,但是正如企业的架构一样,当面临调整的时候,也会面临重大的挑战。当我们面临将已经标准化的代码架构进行重构的时候,这样的重构成本会相当的高。所以在制定标准化中需要严格按照“SOLID”的原则下进行。虽然这是有点古老的原则,但是没有这些原则指导,制定的标准化,寸步难行。
更好,更快
无论在什么情况下,在编程里面完成任务是重中之重(重要的事情要重复一下)。只有先完成,我们才能去说追求更多——让程序运行的更好,更快。要做到这个目标,必须要在时间复杂度和空间复杂度上下更多的功夫。这是《数据结构》这门课程最基础、最简单,也是贯通全书的知识点。最近在阅读《Redis设计与实现》一书的时候,更是充分地了解到这两点的重要,几乎是所有操作都是O(1)的时间复杂度,在它各种数据结构和对象的实现上,都体现了尽量少的存储空间做尽量多的事情。Do less,get more!
我们虽然谨记时间复杂度和空间复杂度,但是不能绝对强调。更好、更快不是单单指这两个基础指标,还有代码的可读性、可扩展性,还有业务之间的耦合度和业务自身的高内聚。如关系型的数据库一样,绝对的范式设计只会存在于实验室。在现实的项目中,为了提高开发效率和查询速度,我们会根据实际需要设计冗余的数据表。所以,在实际开发中我们总要适当的进行取舍,根据业务的特性和实际场景,牺牲一些时间复杂度和空间复杂度,以达到整体更高的收益。
NO.5重构带来了什么?
开发效率的极大提升
之前有一段时间,有好几个项目我需要同时开发,但是我都可以完全轻松的掌控,而且是保质保量地按时完成了开发任务。因为我在不断地重构中,整理出了一套自己的编码标准,在这套编码标准下,设计好了代码思路后,进入了编程阶段的我无需过多的进行思考,只要我按照自己制定好的道路和代码层次去简单编码即可。而在测试阶段出了一些bug,更多的是产品设计上的缺陷而需要产品完善的地方。
对于目前来说,写一个新的业务,就是在一个零零散散的积木进行快速拼凑,再为这个项目添加上它自身的特有的色彩即可。
开发思路的改变
对于我而言,我是在完善自己的代码工具库。首先如何将一些常见的代码逻辑进行不断抽象进行封装,变成自己的工具;如何将自己的工具变得更加快捷便利,当下的工具是否需要进行调整来适应业务发展;在什么业务场景下,哪些工具可以复用或者抽取形成一个微服务。
NO.6重构边界
在《重构》中说到,重构是在时刻进行着的。对于个人开发业务而言,这是正确的,因为需求触发改变。但是对于整体架构而言,我们更多的是在固定的框架下,默默耕耘。
正如在一栋楼房里面,我们可以花一天的时间对其中一个房间进行重新摆设,而对整栋楼房的影响近乎微乎其微。因为每个人有自己的风格,对房间按照自己的心意进行重构,无可厚非。但是要对整栋楼房进行重构,那是一个极其漫长的过程,再者,如果业务没有达到飞跃性的增长,整栋楼房的坚固稳定尤其重要,毕竟人都要舒舒服服地住在里面,谁能容忍,三天两头在自己家里进行装修?
故此,重构的边界显而易见!其实当“人口”激增了,一栋楼房不能再适应的时候,如果有充裕的时间和地方,重建一栋无疑是最好的选择。