`

一篇讲透重构之道

    博客分类:
  • java
 
阅读更多

前言

“重构” 这个词对于大部分工程师来说都不陌生。实际上大部分人都只是 “听得多做得少”,真正进行过代码重构的人不多,而把持续重构作为开发的一部分的人,就更是少之又少了。

一方面,重构代码对一个工程师能力的要求,要比单纯写代码高得多。重构需要你能洞察出代码存在的坏味道或者设计上的不足,并且能合理、熟练地利用设计思想、原则、模式、编程规范等理论知识解决这些问题。

另一方面,很多工程师对为什么要重构、到底重构什么、什么时候重构、又该如何重构等相关问题理解不深,对重构没有系统性、全局性的认识,面对一堆烂代码,没有重构技巧的指导,只能想到哪改到哪,并不能全面地改善代码质量。

重构主要包含以下几个方面:

  • 对重构概括性的介绍,包括重构的目的(why)、对象(what)、时机(when)、方法(how);
  • 保证重构不出错的手段,重点讲解单元测试和代码的可测试性;
  • 不同规模的重构,重点讲解大规模高层次重构(比如系统、模块、代码结构、类与类之间的交互等的重构)和小规模低层次重构(类、函数、变量等的重构)。

重构的目的:为什么要重构(why)?

大师是怎么描述重构的。软件设计大师 Martin Fowler 是这样定义重构的:“重构是一种对软件内部结构的改善,目的是在不改变软件的可见行为的情况下,使其更易理解,修改成本更低。”

实际上,当讲到重构的时候,很多书籍都会引用这个定义。这个定义中有一个值得强调的点:“重构不改变外部的可见行为”。我们可以把重构理解为,在保持功能不变的前提下,利用设计思想、原则、模式、编程规范等理论来优化代码,修改设计上的不足,提高代码质量。

简单了解重构的定义之后,我们重点来看一下,为什么要进行代码重构?

首先,重构是时刻保证代码质量的一个极其有效的手段,不至于让代码腐化到无可救药的地步。项目在演进,代码不停地在堆砌。如果没有人为代码的质量负责任,代码总是会往越来越混乱的方向演进。当混乱到一定程度之后,量变引起质变,项目的维护成本已经高过重新开发一套新代码的成本,想要再去重构,已经没有人能做到了。

其次,优秀的代码或架构不是一开始就能完全设计好的,就像优秀的公司和产品也都是迭代出来的。我们无法 100% 遇见未来的需求,也没有足够的精力、时间、资源为遥远的未来买单,所以,随着系统的演进,重构代码也是不可避免的。

最后,重构是避免过度设计的有效手段。在我们维护代码的过程中,真正遇到问题的时候,再对代码进行重构,能有效避免前期投入太多时间做过度的设计,做到有的放矢。

除此之外,重构对一个工程师本身技术的成长也有重要的意义。

从重构的定义来看,重构实际上是对我们学习的经典设计思想、设计原则、设计模式、编程规范的一种应用。重构实际上就是将这些理论知识,应用到实践的一个很好的场景,能够锻炼我们熟练使用这些理论知识的能力。除此之外,平时堆砌业务逻辑,你可能总觉得没啥成长,而将一个比较烂的代码重构成一个比较好的代码,会让你很有成就感。

除此之外,重构能力也是衡量一个工程师代码能力的有效手段。所谓 “初级工程师在维护代码,高级工程师在设计代码,资深工程师在重构代码”,这句话的意思是说,初级工程师在已有代码框架下修改 bug、修改添加功能代码;高级工程师从零开始设计代码结构、搭建代码框架;而资深工程师为代码质量负责,需要发觉代码存在的问题,重构代码,时刻保证代码质量处于一个可控的状态。

重构的对象:到底重构什么(what)?

根据重构的规模,我们可以笼统地分为大规模高层次重构(以下简称为 “大型重构”)和小规模低层次的重构(以下简称为 “小型重构”)。

大型重构指的是对顶层代码设计的重构,包括:系统、模块、代码结构、类与类之间的关系等的重构,重构的手段有:分层、模块化、解耦、抽象可复用组件等等。这类重构的工具就是我们学习过的那些设计思想、原则和模式。这类重构涉及的代码改动会比较多,影响面会比较大,所以难度也较大,耗时会比较长,引入 bug 的风险也会相对比较大。

小型重构指的是对代码细节的重构,主要是针对类、函数、变量等代码级别的重构,比如规范命名、规范注释、消除超大类或函数、提取重复代码等等。小型重构更多的是利用我们能后面要讲到的编码规范。这类重构要修改的地方比较集中,比较简单,可操作性较强,耗时会比较短,引入 bug 的风险相对来说也会比较小。你只需要熟练掌握各种编码规范,就可以做到得心应手。

重构的时机:什么时候重构(when)?

搞清楚了为什么重构,到底重构什么,我们再来看一下,什么时候重构?是代码烂到一定程度之后才去重构吗?当然不是。因为当代码真的烂到出现 “开发效率低,招了很多人,天天加班,出活却不多,线上 bug 频发,领导发飙,中层束手无策,工程师抱怨不断,查找 bug 困难” 的时候,基本上重构也无法解决问题了。

我个人比较反对,平时不注重代码质量,堆砌烂代码,实在维护不了了就大刀阔斧地重构、甚至重写的行为。有时候项目代码太多了,重构很难做得彻底,最后又搞出来一个 “四不像的怪物”,这就更麻烦了!所以,寄希望于在代码烂到一定程度之后,集中重构解决所有问题是不现实的,我们必须探索一条可持续、可演进的方式。

所以,我特别提倡的重构策略是持续重构。平时没有事情的时候,你可以看看项目中有哪些写得不够好的、可以优化的代码,主动去重构一下。或者,在修改、添加某个功能代码的时候,你也可以顺手把不符合编码规范、不好的设计重构一下。总之,就像把单元测试、Code Review 作为开发的一部分,我们如果能把持续重构也作为开发的一部分,成为一种开发习惯,对项目、对自己都会很有好处。

尽管我们说重构能力很重要,但持续重构意识更重要。我们要正确地看待代码质量和重构这件事情。技术在更新、需求在变化、人员在流动,代码质量总会在下降,代码总会存在不完美,重构就会持续在进行。时刻具有持续重构意识,才能避免开发初期就过度设计,避免代码维护的过程中质量的下降。而那些看到别人代码有点瑕疵就一顿乱骂,或者花尽心思去构思一个完美设计的人,往往都是因为没有树立正确的代码质量观,没有持续重构意识。

重构的方法:又该如何重构(how)?

前面我们讲到,按照重构的规模,重构可以笼统地分为大型重构和小型重构。对于这两种不同规模的重构,我们要区别对待。

对于大型重构来说,因为涉及的模块、代码会比较多,如果项目代码质量又比较差,耦合比较严重,往往会牵一发而动全身,本来觉得一天就能完成的重构,你会发现越改越多、越改越乱,没一两个礼拜都搞不定。而新的业务开发又与重构相冲突,最后只能半途而废,revert 掉所有的改动,很失落地又去堆砌烂代码了。

在进行大型重构的时候,我们要提前做好完善的重构计划,有条不紊地分阶段来进行。每个阶段完成一小部分代码的重构,然后提交、测试、运行,发现没有问题之后,再继续进行下一阶段的重构,保证代码仓库中的代码一直处于可运行、逻辑正确的状态。每个阶段,我们都要控制好重构影响到的代码范围,考虑好如何兼容老的代码逻辑,必要的时候还需要写一些兼容过渡代码。只有这样,我们才能让每一阶段的重构都不至于耗时太长(最好一天就能完成),不至于与新的功能开发相冲突。

大规模高层次的重构一定是有组织、有计划,并且非常谨慎的,需要有经验、熟悉业务的资深同事来主导。而小规模低层次的重构,因为影响范围小,改动耗时短,所以,只要你愿意并且有时间,随时都可以去做。实际上,除了人工去发现低层次的质量问题,我们还可以借助很多成熟的静态代码分析工具(比如 CheckStyle、FindBugs、PMD),来自动发现代码中的问题,然后针对性地进行重构优化。

对于重构这件事情,资深的工程师、项目 leader 要负起责任来,没事就重构一下代码,时刻保证代码质量处在一个良好的状态。否则,一旦出现 “破窗效应”,一个人往里堆了一些烂代码,之后就会有更多的人往里堆更烂的代码。毕竟往项目里堆砌烂代码的成本太低了。不过,保持代码质量最好的方法还是打造一种好的技术氛围,以此来驱动大家主动去关注代码质量,持续重构代码。

重点回顾

今天的讲解让你对重构有个正确的、全局性的认知,建立持续重构意识。这可能比教会你一些重构技巧更重要,因为很多技术问题本身就不是单纯靠技术来解决的,更重要的是要有这种认知和意识。

1. 重构的目的:为什么重构(why)?

对于项目来言,重构可以保持代码质量持续处于一个可控状态,不至于腐化到无可救药的地步。对于个人而言,重构非常锻炼一个人的代码能力,并且是一件非常有成就感的事情。它是我们学习的经典设计思想、原则、模式、编程规范等理论知识的练兵场。

2. 重构的对象:重构什么(what)?

按照重构的规模,我们可以将重构大致分为大规模高层次的重构和小规模低层次的重构。大规模高层次重构包括对代码分层、模块化、解耦、梳理类之间的交互关系、抽象复用组件等等。这部分工作利用的更多的是比较抽象、比较顶层的设计思想、原则、模式。小规模低层次的重构包括规范命名、注释、修正函数参数过多、消除超大类、提取重复代码等等编程细节问题,主要是针对类、函数级别的重构。小规模低层次的重构更多的是利用编码规范这一理论知识。

3. 重构的时机:什么时候重构(when)?

我反复强调,我们一定要建立持续重构意识,把重构作为开发必不可少的部分,融入到日常开发中,而不是等到代码出现很大问题的时候,再大刀阔斧地重构。

4. 重构的方法:如何重构(how)?

 

大规模高层次的重构难度比较大,需要组织、有计划地进行,分阶段地小步快跑,时刻让代码处于一个可运行的状态。而小规模低层次的重构,因为影响范围小,改动耗时短,所以,只要你愿意并且有时间,随时随地都可以去做。

分享到:
评论

相关推荐

    重构java代码简洁之道

    "重构Java代码简洁之道"的主题旨在探讨如何通过有效的重构技术提升代码质量、可读性和可维护性,同时保持代码的简洁性。这对于任何Java开发者来说,都是一个值得深入学习的课题。 重构是一种在不改变代码外在行为的...

    重构遗留代码,浮现架构之道-2013.04.02.pdf

    为了应对这一挑战,《重构遗留代码,浮现架构之道》这一文献深入探讨了如何通过重构技术来改善遗留代码,使架构之道重新浮现。 #### 二、理解遗留代码与架构之道 **1. 遗留代码的本质** - **定义**:文中提到,...

    java代码重构经验分享

    Java 代码重构经验分享 Java 代码重构是指在不改变外部行为的情况下,修改代码的内部结构,以提高代码的可维护性、可读性和可扩展性。本文总结了 Java 代码重构的经验和技术规范,包括重构要求...反例之一:丢弃异常。

    阿里巴巴-孤尽-软件工程危机与重构之道.pdf

    阿里巴巴-孤尽-软件工程危机与重构之道

    【EMD重构】.rar_EMD重构函数_IMF变量重构_tomorrowi4n_模态分解_重构

    在描述中提到的"对经验模态分解后的各分量IMF进行重构代码,函数可直接调用",意味着这个压缩包中包含了一个名为"EMDchonggou.m"的MATLAB脚本文件,该文件提供了实现IMF重构功能的代码。用户可以直接运行这个函数,...

    系统重构.pdf 侯捷

    #### 一、系统重构的概念与背景 - **定义**:系统重构是指在不改变软件外部行为的前提下,对其内部结构进行调整以提高代码质量和可维护性的过程。这一概念最初源于Smalltalk社区,并逐渐扩展到其他编程语言领域。 -...

    27丨理论一:什么情况下要重构?到底重构什么?又该如何重构?1

    重构是软件开发过程中的一个重要环节,它涉及到代码的优化、设计改进和质量提升,而不改变程序的外部行为。本文将详细探讨重构的目的、对象、时机和方法,帮助开发者理解和掌握重构的核心理念。 **重构的目的(Why...

    重构_重构_改善既有代码_

    这本书是每一位致力于提升软件工程实践水平的开发者,尤其是架构师的必读之作。 重构的核心概念在于,当代码变得难以理解和维护时,我们需要对其进行整理和优化,使其更清晰、更简洁,同时保持原有的功能。这一过程...

    软件重构讲义,自己整理的一个软件重构ppt

    《软件重构讲义》是关于软件开发中重构技术的一份资料,主要涵盖了重构的基本概念、目的、时机选择、流程以及代码质量改进等方面。重构是一种在不改变软件功能的前提下,通过改进代码结构以提升软件设计质量、可维护...

    重构(Refactoring)英文版

    3. **保持简洁**:重构的目标之一就是简化代码结构。这不仅包括去除不必要的代码,还包括简化逻辑结构,使得代码更加清晰易懂。 4. **遵循设计模式**:在重构的过程中,应该参考并遵循一些已知的设计模式,这些模式...

    代码重构.pdf

    《代码重构》一书由Martin Fowler编写,是软件开发领域中关于代码质量提升的经典之作。书中详细阐述了重构代码的必要性、重构的时机以及如何安全地重构代码。重构指的是在不改变软件外部行为的前提下,改进其内部...

    Python代码重构的艺术:探索自动化重构工具

    2. **PyCharm**:作为一款流行的Python集成开发环境,PyCharm内置了一系列强大的重构功能。除了基本的重命名和提取方法之外,PyCharm还支持重构整个类或模块,甚至能够处理复杂的多文件重构任务。 3. **Vim**:尽管...

    软件重构 软件重构经典PPT

    【软件重构】是一种重要的软件开发实践,旨在提升代码的质量、可读性和可维护性,同时保持软件原有的功能和外部行为不变。这一概念由 Martin Fowler 在他的著作《重构:改善既有代码的设计》中进行了深入阐述。重构...

    重构手册 Professional Refactoring Workbook

    “设计模式”作为本书的标签之一,表明重构与经典的设计模式密切相关。在重构过程中,往往需要运用到如工厂模式、单例模式、观察者模式等经典设计模式,以解决特定的软件设计问题。通过重构,可以将代码从原始的、...

    重构pdf+chm版本

    《重构:改善既有代码的设计》是一本由Martin Fowler所著的经典IT著作,它在软件开发领域具有极高的影响力。这本书的PDF和CHM版本都包含了关于重构和代码优化的深入探讨,是学习重构技术的理想资源。 重构是软件...

    [电子书] 重构与模式

    《重构与模式》是软件开发领域的一本经典著作,作者为Addison-Wesley Professional出版社。这本书主要探讨了如何在实际编程过程中有效地进行重构,并将其与设计模式相结合,以提升软件质量和可维护性。 重构是一种...

    重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt

    重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt重构ppt

Global site tag (gtag.js) - Google Analytics