重构(Refactoring)就是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。  也许有人会问,为什么不在项目开始时多花些时间把设计做好,而要以后花时间来重构呢?要知道一个完美得可以预见未来任何变化的设计,或一个灵活得可以容纳任何扩展的设计是不存在的。系统设计人员对即将着手的项目往往只能从大方向予以把控,而无法知道每个细枝末节,其次永远不变的就是变化,提出需求的用户往往要在软件成型后,始才开始"品头论足",系统设计人员毕竟不是先知先觉的神仙,功能的变化导致设计的调整再所难免。所以"测试为先,持续重构"作为良好开发习惯被越来越多的人所采纳,测试和重构像黄河的护堤,成为保证软件质量的法宝。

为什么要重构(Refactoring)

在不改变系统功能的情况下,改变系统的实现方式。为什么要这么做?投入精力不用来满足客户关心的需求,而是仅仅改变了软件的实现方式,这是否是在浪费客户的投资呢?
重构的重要性要从软件的生命周期说起。软件不同与普通的产品,他是一种智力产品,没有具体的物理形态。一个软件不可能发生物理损耗,界面上的按钮永远不会因为按动次数太多而发生接触不良。那么为什么一个软件制造出来以后,却不能永远使用下去呢?
对软件的生命造成威胁的因素只有一个:需求的变更。一个软件总是为解决某种特定的需求而产生,时代在发展,客户的业务也在发生变化。有的需求相对稳定一些,有的需求变化的比较剧烈,还有的需求已经消失了,或者转化成了别的需求。在这种情况下,软件必须相应的改变。
考虑到成本和时间等因素,当然不是所有的需求变化都要在软件系统中实现。但是总的说来,软件要适应需求的变化,以保持自己的生命力。
这就产生了一种糟糕的现象:软件产品最初制造出来,是经过精心的设计,具有良好架构的。但是随着时间的发展、需求的变化,必须不断的修改原有的功能、追加新的功能,还免不了有一些缺陷需要修改。为了实现变更,不可避免的要违反最初的设计构架。经过一段时间以后,软件的架构就千疮百孔了。bug越来越多,越来越难维护,新的需求越来越难实现,软件的构架对新的需求渐渐的失去支持能力,而是成为一种制约。最后新需求的开发成本会超过开发一个新的软件的成本,这就是这个软件系统的生命走到尽头的时候。
重构就能够最大限度的避免这样一种现象。系统发展到一定阶段后,使用重构的方式,不改变系统的外部功能,只对内部的结构进行重新的整理。通过重构,不断的调整系统的结构,使系统对于需求的变更始终具有较强的适应能力。
通过重构可以达到以下的目标:
·持续纠偏和改进软件设计
重构和设计是相辅相成的,它和设计彼此互补。有了重构,你仍然必须做预先的设计,但是不必是最优的设计,只需要一个合理的解决方案就够了,如果没有重构、程序设计会逐渐腐败变质,愈来愈像断线的风筝,脱缰的野马无法控制。重构其实就是整理代码,让所有带着发散倾向的代码回归本位。
·使代码更易为人所理解
Martin Flower在《重构》中有一句经典的话:"任何一个傻瓜都能写出计算机可以理解的程序,只有写出人类容易理解的程序才是优秀的程序员。"对此,笔者感触很深,有些程序员总是能够快速编写出可运行的代码,但代码中晦涩的命名使人晕眩得需要紧握坐椅扶手,试想一个新兵到来接手这样的代码他会不会想当逃兵呢?
软件的生命周期往往需要多批程序员来维护,我们往往忽略了这些后来人。为了使代码容易被他人理解,需要在实现软件功能时做许多额外的事件,如清晰的排版布局,简明扼要的注释,其中命名也是一个重要的方面。一个很好的办法就是采用暗喻命名,即以对象实现的功能的依据,用形象化或拟人化的手法进行命名,一个很好的态度就是将每个代码元素像新生儿一样命名,也许笔者有点命名偏执狂的倾向,如能荣此雅号,将深以此为幸。
对于那些让人充满迷茫感甚至误导性的命名,需要果决地、大刀阔斧地整容,永远不要手下留情!
·帮助发现隐藏的代码缺陷
孔子说过:温故而知新。重构代码时逼迫你加深理解原先所写的代码。笔者常有写下程序后,却发生对自己的程序逻辑不甚理解的情景,曾为此惊悚过,后来发现这种症状居然是许多程序员常患的"感冒"。当你也发生这样的情形时,通过重构代码可以加深对原设计的理解,发现其中的问题和隐患,构建出更好的代码。
·从长远来看,有助于提高编程效率
当你发现解决一个问题变得异常复杂时,往往不是问题本身造成的,而是你用错了方法,拙劣的设计往往导致臃肿的编码。
改善设计、提高可读性、减少缺陷都是为了稳住阵脚。良好的设计是成功的一半,停下来通过重构改进设计,或许会在当前减缓速度,但它带来的后发优势却是不可低估的。

何时着手重构(Refactoring)

重构(Refactoring)的难题

对开发者而言,对象数据库既有帮助也有妨碍。某些面向对象数据库提供不同版本的对象之间的自动迁移功能,这减少了数据迁移时的工作量,但还是会损失一定时间。如果各数据库之间的数据迁移并非自动进行,你就必须自行完成迁移工作,这个工作量可是很大的。这种情况下你必须更加留神classes内的数据结构变化。你仍然可以放心将classes的行为转移过去,但转移值域(field)时就必须格外小心。数据尚未被转移前你就得先运用访问函数(accessors)造成「数据已经转移」的假象。一旦你确定知道「数据应该在何处」时,就可以一次性地将数据迁移过去。这时惟一需要修改的只有访问函数(accessors),这也降低了错误风险。
「保留旧接口」的办法通常可行,但很烦人。起码在一段时间里你必须建造(build)并维护一些额外的函数。它们会使接口变得复杂,使接口难以使用。还好我们有另一个选择:不要发布(publish)接口。当然我不是说要完全禁止,因为很明显你必得发布一些接口。如果你正在建造供外部使用的APIs,像Sun所做的那样,肯定你必得发布接口。我之所以说尽量不要发布,是因为我常常看到一些开发团队公开了太多接口。我曾经看到一支三人团队这么工作:每个人都向另外两人公开发布接口。这使他们不得不经常来回维护接口,而其实他们原本可以直接进入程序库,径行修改自己管理的那一部分,那会轻松许多。过度强调「代码拥有权」的团队常常会犯这种错误。发布接口很有用,但也有代价。所以除非真有必要,别发布接口。这可能意味需要改变你的代码拥有权观念,让每个人都可以修改别人的代码,以运应接口的改动。以搭档(成对)编程(Pair Programming)完成这一切通常是个好主意。
Java之中还有一个特别关于「修改接口」的问题:在throws子句中增加一个异常。这并不是对签名式(signature)的修改,所以你无法以delegation(委托手法)隐藏它。但如果用户代码不作出相应修改,编译器不会让它通过。这个问题很难解决。你可以为这个函数选择一个新名tion(可控式异常)转换成一个unchecked exception(不可控异常)。你也可以抛出一个unchecked异常,不过这样你就会失去检验能力。如果你那么做,你可以警告调用者:这个unchecked异常日后会变成一个checked异常。这样他们就有时间在自己的代码中加上对此异常的处理。出于这个原因,我总是喜欢为整个package定义一个superclass异常(就像java.sql的SQLException),并确保所有public函数只在自己的throws子句中声明这个异常。这样我就可以随心所欲地定义subclass异常,不会影响调用者,因为调用者永远只知道那个更具一般性的superclass异常。

重构(Refactoring)与设计

这种转变导致一个重要结果:软件设计朝向简化前进了一大步。过去未曾运用重构时,我总是力求得到灵活的解决方案。任何一个需求都让我提心吊胆地猜疑:在系统寿命期间,这个需求会导致怎样的变化?由于变更设计的代价非常高昂,所以我希望建造一个足够灵活、足够强固的解决方案,希望它能承受我所能预见的所有需求变化。问题在于:要建造一个灵活的解决方案,所需的成本难以估算。灵活的解决方案比简单的解决方案复杂许多,所以最终得到的软件通常也会更难维护 — 虽然它在我预先设想的??方向上,你也必须理解如何修改设计。如果变化只出现在一两个地方,那不算大问题。然而变化其实可能出现在系统各处。如果在所有可能的变化出现地点都建立起灵活性,整个系统的复杂度和维护难度都会大大提高。当然,如果最后发现所有这些灵活性都毫无必要,这才是最大的失败。你知道,这其中肯定有些灵活性的确派不上用场,但你却无法预测到底是哪些派不上用场。为了获得自己想要的灵活性,你不得不加入比实际需要更多的灵活性。

重构与性能(Performance)

在性能优化阶段中,你首先应该以一个量测工具监控程序的运行,让它告诉你程序中哪些地方大量消耗时间和空间。这样你就可以找出性能热点(hot spot)所在的一小段代码。然后你应该集中关切这些性能热点,并使用前述「持续关切法」中的优化手段来优化它们。由于你把注意力都集中在热点上,较少的工作量便可显现较好的成果。即便如此你还是必须保持谨慎。和重构一样,你应该小幅度进行修改。每走一步都需要编译、测试、再次量测。如果没能提高性能,就应该撤销此次修改。你应该继续这个「发现热点、去除热点」的过程,直到获得客户满意的性能为止。关于这项技术,McConnell 【McConnell】 为我们提供了更多信息。

来自百度,为什么要重构(Refactoring)相关推荐

  1. C:\WINDOWS\WinSxS目录介绍,来自百度词条

    C:\WINDOWS\WinSxS目录介绍,来自百度词条 来源:重庆沙坪坝区网吧联盟    发表时间:2010-08-16 03:22    查看:9次     WinSxS是Windows目录下一个 ...

  2. 来自百度的一篇如何关闭Centos7的防火墙以及如何永久关闭防火墙的指令教学【转载】

    转载:来自百度的一篇如何关闭Centos7的防火墙以及如何永久关闭防火墙的指令教学 使用命令:systemctl status firewalld.service 查看防火墙状态 2 执行后可以看到绿 ...

  3. 来自百度的71款开源项目

    百度,一家让人既爱又恨的企业,血友吧贴吧被卖,魏则西事件的持续发酵,一时间将百度推到了舆论的风口浪尖上.是非对错,我们在这里也不多做评判,本文呢为大家整理了百度开源的70+项目,看看有没有感兴趣的.本 ...

  4. 开源巨献:来自百度的71款开源项目

    百度,一家让人既爱又恨的企业,血友吧贴吧被卖,魏则西事件的持续发酵,一时间将百度推到了舆论的风口浪尖上.是非对错,我们在这里也不多做评判,本文呢为大家整理了百度开源的70+项目,看看有没有感兴趣的.本 ...

  5. 水彩入门之画材 来自百度贴吧

    一 画笔的种类 笔是画水彩的主要工具,不同种类和型号的画笔能产生不同的形状与轻重的笔触,会关系到画面艺术效果及塑造形象的生动性.对于顺利作画至关重要,因而了解笔的种类及特点是很有必要的. 水彩画笔的毛 ...

  6. 最值得研究的开源框架:来自百度的71款开源项目

    百度,一家让人既爱又恨的企业,血友吧贴吧被卖,魏则西事件的持续发酵,一时间将百度推到了舆论的风口浪尖上.是非对错,我们在这里也不多做评判,本文呢为大家整理了百度开源的70+项目,看看有没有感兴趣的.本 ...

  7. Google+内幕:搜索巨人的社交网络努力【来自百度百科】

    今天,世界上最大的搜索公司 Google 正式发起自己在社交网络领域的又一次重要攻势.此次发布的产品名为 Google+,观察者们可能会怀疑它不过是这家在社交网络一直没摸到门道的公司的又一次无谓努力. ...

  8. 上海电子地图 来自百度电子地图库 含15、17、最高级别19级地图

    上海电子地图 来自谷歌电子地图库 含15.17.最高级别19级地图,一般来说商业用图差不多就是17级左右,提供的下载完全满足大多数人浏览使用. 百度网盘下载资源:http://pan.baidu.co ...

  9. 2008下半年来自百度的博客-002

    我的空间  写新文章 上传新照片 选择模板 选择主页类型 #hi{ position:relative; zoom:1;} #hiMsg{display:none;top:2px;height:17p ...

  10. 关于魏则西事件——听听来自百度的声音

    今天,我们不聊技术,聊聊这几天被大家推至沸腾的魏则西事件.作为一个百度人,我觉得有必要站出来为百度说几句公道话 ? 当人们千夫所指都在骂百度时,人们不应该理性的思考更深层次的原因吗?不是更应该指责医院 ...

最新文章

  1. 一文搞懂TCP的三次握手和四次挥手
  2. JAVA 多用户商城系统b2b2c-服务容错保护(Hystrix依赖隔离)
  3. 应用分析:CIO须注意SOA使用中的五大隐患
  4. Logistic Regression 之基础知识准备
  5. thinkphp5+workerman搭建微信小程序socket后台,建立自己的聊天室
  6. JAVA WEB开发环境搭建教程
  7. Java并发(十九):final实现原理
  8. c语言画谢宾斯基三角形
  9. iPhone 13需求强劲推动 分析师预计iPhone四季度将销售超过8000万部
  10. PRICAI 2016 论文精选 | 基于车辆优先级优化交通系统的道路分布
  11. AngularJS Provider/Service/Factory 使用
  12. 宏批量替换多个word指定文字
  13. 【八】【vlc-android】vlc-vout视频流输出端源码分析
  14. mysql插入数据会失败?为什么?
  15. Abp 项目生成数据到数据库
  16. DCM: 中间件家族迎来新成员
  17. python,抓取豆瓣电影,再也不用担心没有看不了的电影了
  18. 基于Python的人脸人眼图像识别处理系统
  19. 【科技百咖】五舟科技CEO谢高辉:国产自主 软硬一体,通过定制化杀出一条血路...
  20. 5 个最适合 Windows的命令行/控制台替代品

热门文章

  1. 在MATLAB中实现均值变点法
  2. OpenCV+Python车牌字符分割和识别入门 (含新能源车牌识别)
  3. 如何锁定win10笔记本键盘
  4. 梁念坚:从MOTO到微软 从无缝连接到统一沟通
  5. Dynamics CRM 为案例起源设置自定义图标
  6. LayaAir引擎78款3D射击主题微信小游戏分享,看看玩过几款!
  7. ios app上架审核被拒及解决总结
  8. android布局事件吗,Android事件分发机制
  9. saas商业模式和架构设计
  10. cgcs2000大地坐标系地图_测绘人必备!从地方坐标系到2000国家大地坐标系的转换...