代码重构简介:(英语:Code refactoring)重构就是在不改变软件系统外部行为的前提下,改善它的内部结构。
为什么要重构(Refactoring)???
为什么要这么做?投入精力仅仅改变了软件的实现方式,这是否是在浪费客户的投资呢?
对软件的生命造成威胁的因素:需求的变更。一个软件总是为解决某种特定的需求而产生,时代在发展,客户的业务也在发生变化。有的需求相对稳定一些,有的需求变化的比较剧烈,还有的需求已经消失了,或者转化成了别的需求。在这种情况下,软件必须作出相应的改变。考虑到成本和时间等因素,当然不是所有的需求变化都要在软件系统中实现。但是总的说来,软件要适应需求的变化,以保持自己的生命力。
这就产生了一种糟糕的现象:软件产品最初制造出来,是经过精心的设计,具有良好架构的。但是随着时间的发展、需求的变化,必须不断的修改原有的功能、追加新的功能,还免不了有一些缺陷需要修改。为了实现变更,不可避免的要违反最初的设计构架。经过一段时间以后,软件的架构就千疮百孔了。bug越来越多,越来越难维护,新的需求越来越难实现,软件的构架对新的需求渐渐的失去支持能力,而是成为一种制约。最后新需求的开发成本会超过开发一个新的软件的成本。最终,该软件的生命到了尽头。
怎样避免这样的现象?
系统发展到一定阶段后,使用重构的方式,不改变系统的外部功能,只对内部的结构进行重新的整理。通过重构,不断的调整系统的结构,使系统对于需求的变更始终具有较强的适应能力。
有些程序员总是能够快速编写出可运行的代码,但代码中晦涩的命名使人晕眩得需要紧握坐椅扶手,试想一个新兵到来接手这样的代码他会不会想当逃兵呢?
软件的生命周期往往需要多批程序员来维护,我们往往忽略了这些后来人。为了使代码容易被他人理解,需要在实现软件功能时做许多额外的事件,如清晰的排版布局,简明扼要的注释,其中命名也是一个重要的方面。
对于那些让人充满迷茫感甚至误导性的命名,需要果决地、大刀阔斧地整容,永远不要手下留情!
孔子说过:温故而知新。重构代码时逼迫你加深理解原先所写的代码。
从长远来看,有助于提高编程效率
为什么要重构:延续软件生命、适应需求变更、加深理解代码、提高自我编程能力
如何实施重构:
何时着手重构(Refactoring)
新官上任三把火,开始一个全新??、脚不停蹄、加班加点,一支声势浩大的千军万”码”夹裹着程序员激情和扣击键盘的鸣金奋力前行,势如破竹,攻城掠地,直指”黄龙府”。开发经理是这支浩浩汤汤代码队伍的统帅,他负责这支队伍的命运,当齐桓公站在山顶上看到管仲训练的队伍整齐划一地前进时,他感叹说”我有这样一支军队哪里还怕没有胜利呢?”。但很遗憾,你手中的这支队伍原本只是散兵游勇,在前进中招兵买马,不断壮大,所以队伍变形在所难免。当开发经理发觉队伍变形时,也许就是克制住攻克前方山头的诱惑,停下脚步整顿队伍的时候了。(什么变形??当项目经理看到下面这些情况就已经变形了:代码中存在重复的代码、过大的类和过长的方法、牵一毛而需要动全身的修改、类之间需要过多的通讯、过度耦合的信息链、各立山头干革命、不完美的设计、缺少必要的注释,重复代码,过长方法就不解释了。牵一发而动全身,当你发现修改一个小功能,或者增加一个小功能,却影响了这里那里。过多的通讯,A类需要调用C类的过多的方法来访问C类的内部数据,这两个类的关系就可以不用分家了。过度耦合,当在代码中看到需要取得一个信息,要调用A类的一个方法调用另外一个B类的方法调用另外一个C类的方法再调用D类的方法…我已经晕bi了,衔接层数太多了,就需要考虑移除一些中间层,或者更直接的调用方法。各立山头,我曾经写了一个处理字符串的一个类,但是没有及时通告团队其他成员,后来发现,项目中有3个处理字符串的类。不完美的设计,不合理,不可扩展性,一次性用品。缺少注释就不用说了,还是说说吧,许多书籍常常提醒防止过多的注释,但是我发现这个担心好像没什么必要,我看到的代码基本上没有注释。往往程序员关注的是功能而非代码注释,毕竟前者更能带来成就感,当过了一段时间再回头补注释,很容易‘提笔忘字,欲言又止’。)
重构(Refactoring)的难题
学习一种可以大幅提高生产力的新技术时,你总是难以察觉其不适用的场合。通常你在一个特定场景中学习它,这个场景往往是个项目。这种情况下你很难看出什么会造成这种新技术成效不彰或甚至形成危害。十年前,对象技术(object tech.)就是如此。
现在,重构的处境也是如此。我们知道重构的好处,我们知道重构可以给我们的工作带来垂手可得的改变。但是我们还没有获得足够的经验,我们还看不到它的局限性。
难题:
数据库(database):结构紧密耦合在一起、数据迁移。
接口(interface):修改错了就gg了。该如何面对那些必须修改「已发布接口」的重构手法?已经发布的接口,就同时维护新旧两个接口,更甚至很多版本的接口。让新旧接口都能继续工作。如果需要修改某个函数名称,留下旧的函数,让旧函数来调用新的函数,不要拷贝函数的实现代码,可能会让你陷入重复代码的泥沼。可以对旧的方法标记“反对”的关键字,比如Java中的deprecated。这样,调用者就会注意到了。
「保留旧接口」的办法通常可行,但很烦人。起码在一段时间里你必须建造(build)并维护一些额外的函数。它们会使接口变得复杂,使接口难以使用。还好我们有另一个选择:不要发布(publish)接口(不要把所有的接口都公开出去),不要过早的发布。
难以通过重构完成的设计改动:将某个设计重构为另一个设计的难度有多大?如果看上去很简单,我就不必太担心选择是否得当,于是我就会选最简单的设计,哪怕它不能覆盖所有潜在需求也没关系。但如果预先看不到简单的重构办法,我就会在设计上投入更多力气。
何时不该重构?
重新编写所有代码的时候。代码实在太混乱,重构它还不如从新写一个来得简单。but作出这种决定很困难。
现有代码根本不能正常运作。重构之前,代码必须起码能够在大部分情况下正常运作。
如果项目已近最后期限。因为已经没有时间了。不过多个项目经验显示:重构的确能够提高生产力。如果最后你没有足够时间,通常就表示你其实早该进行重构。
关于如何实施代码重构
常说事不过三,但也有再三强调。
1.添加功能时重构
2.修补错误时重构
3.复审代码时重构
关于如何实施重构,这个不能泛泛而谈。必须自己理解总结。
另外,如果需要在重构方面有所见长的话,可以看看这本书,《重构》
看到简书上有人读了这本书之后写了一篇,地址://www.greatytc.com/p/dac7979f5a29?ref=myread个人觉得还是写得很好的,在这里推荐一下。