大话重构
重构不是一个阳春白雪的高级玩意儿,它是一种习惯,一种良好的编程习惯。这种习惯让我们迅速由菜鸟转变为大牛,可以编写出高质量、优秀的程序;它是遗留系统的一剂良药,它改变了我们的设计思路,让我们不再为不确定的将来过度设计,让设计回归简单与纯真。而这里正是学习“重构”这种优秀设计的家园。
充满诗意的联盟
嘴里工作者,靠伶牙俐齿打天下的说
展开
-
大话重构连载19:大对象的演化过程
很好,我们终于迈出了重构的第一步,而这第一步我们瞄准了代码问题的重灾区——超级大函数。超级大函数之所以是代码问题的重灾区,就是因为它们往往难于阅读、难于维护。面对大函数我们采取的办法是拆分,以功能为核心将其拆分成一个一个独立的函数。拆分后的程序变得易于阅读了,因为要读懂程序你不再需要读完所有代码,选择性的读取那些顶级函数,只需了了数行代码,你就可以明白整个程序。但是,当我们将数千行的大函数分解成数十个小函数时,另一个问题出现了。想象一下,数十个函数被杂乱无章地堆放在一个对象中,看看就让人头疼。实际上,我们原创 2014-11-17 09:36:51 · 1260 阅读 · 0 评论 -
大话重构连载18:最常见的问题
使用抽取方法,虽然道理十分简单,但实际操作起来却并不是那么容易的。完成抽取方法最大的困难,就是如何处理抽取函数与原函数的数据交换。如同将一颗大树从土壤里拔出来,盘根错节的根茎,那是剪不断理还乱。当代码还没有被抽取出来之前,它们与其它程序都是在一个函数的内部,因此各个代码段可以毫无顾忌地相互交互数据。但当我们将代码从原函数中抽取出来时,抽取出来的代码与原函数中的代码就形成了一道墙,要交换的数据只能通过参数与返回值进行交互,这将给我们带来诸多麻烦。原创 2014-11-02 17:24:13 · 1099 阅读 · 0 评论 -
大话重构连载17:抽取方法的实践
说了那么多理论,我们来看看怎样使用抽取方法来重构遗留系统。如前所述,重构的过程首先是阅读程序代码,边阅读边整理程序。将功能相对独立的代码段放在一起,在前面加上注释。调整一些程序的顺序,将相关的代码尽量放在一起,但要保证程序执行的结果不会发生改变。比较典型的,将变量的定义与使用变量的代码放在一起。这个步骤比较实用,因为许多的遗留系统,其代码都有一个坏毛病,就是在程序开始时定义一大堆变量,但要弄清这些变量都用来做什么,却十分困难。边读边调整,将变量的定义逐渐迁移到使用它的代码段中,将大大提高代码可读性,你甚至会原创 2014-10-29 09:25:10 · 1087 阅读 · 0 评论 -
大话重构连载16:超级大函数
事情总是这样的:当我们对一个遗留系统一忍再忍,再忍,忍,还要忍……终于积攒到某一天,实在忍无可忍了,拍案而起,不能再忍了,重构!!!事情就这样发生了。然而,在这时你突然发现,重构的工作千头万绪,真不知从何开始。堆积如山的问题此起彼伏,期望修改的设计思绪万千。这里有个想法,那里有个思路,什么都想做,却什么都做不了,真是脑子里一团乱麻。这时候,没有一个合理的步骤,清晰的计划,瞎干蛮干是十分危险的,它会为你的重构带来不可预期的未来。无数次的经验告诉我,不论是什么系统,采用什么架构,从分解大函数开始,肯定没有错。原创 2014-10-18 22:55:38 · 1092 阅读 · 0 评论 -
大话重构连载15:采用Mock技术完成测试
第五次重构我们引入了数据库的设计,用户信息要从数据库中读取,问候语库存储在数据库中,并支持添加与更新。数据库的引入使自动化测试变得困难了,因为数据状态总是变化着的,而这种变化使得测试过程不能复现,这是我们不愿看到的。因此,我们在设计时将业务与数据库访问分离,形成了UserDao与GreetingRuleDao。此时,我们的设计应当遵从“依赖反转”原则,即将UserDao与GreetingRuleDao设计成接口,并编写它们的实现UserDaoImpl与GreetingRuleDaoImpl。这样设计就为我们原创 2014-09-21 12:53:41 · 1153 阅读 · 0 评论 -
大话重构连载14:我们是这样自动化测试的
说了那么多,让我们用示例看看,系统重构是应该怎样做自动化测试的。还是回到前面那个HelloWorld的例子(详见 3.3 小步快跑是这样玩的),该类中有一个sayHello()方法,只要我们输入当前的时间与用户名,就返回对该用户的问候语。如果当前时间是上午,则返回“Hi, XXX. Good morning!”;如果是下午,则返回“Hi, XXX. Good afternoon!”;如果是晚上,则返回“Hi, XXX. Good Night!”,这是HelloWorld这个程序实现的功能。然后我们开始为这原创 2014-09-18 01:06:24 · 1162 阅读 · 0 评论 -
大话重构连载13:自动化测试——想说爱你不容易
正如许多事情都有其两面性一样,测试方法也是这样。要保证测试方法正确,最简单、最直观地想法就是多写些测试用例,从更多地角度去测试,但这必然增加我们的测试成本。小步快跑要求我们频繁进行测试,假如我们重构的周期是20分钟,但测试却要花掉10分钟,那么这样的成本就实在太大了。假如这种测试还是开发人员手工测试,每天都有对同样的测试反复执行数十遍,那么开发人员估计就要疯掉了。你可能立即就想到自动化测试了。是的,在许多重构的书籍中,大师们都建议我们在重构开始前,首先建立自动化测试机制。但遗憾的是,我经过多年的实践总结出原创 2014-09-09 10:58:31 · 924 阅读 · 0 评论 -
大话重构连载12:你不能没有保险索
通过前面的描述你已经对重构中“小步快跑”的开发模式有了一个清楚的认识。学会和习惯小步快跑的开发模式,对于重构工作极其重要,因为它让这种大范围、大幅度修改代码的重构工作变得不再像以往那样让人胆战心惊。究其原因,虽然从结果上是在大范围、大幅度调整,但每一步却是小范围、小福度调整,并且能保证每一步都是正确的。然而,这里有一个非常重要的假设条件,那就是“保证每一步都是正确的”,这是怎么保证的呢?就这个问题,我们需要展开来认真讨论讨论。原创 2014-09-08 07:04:36 · 944 阅读 · 0 评论 -
大话重构连载11:小步快跑是这样玩的
说了那么多,相信你对小步快跑的概念有了一个初步的印象,但理解还不是很深。让我们来看一看一个实际工作中的例子,来亲身感受一下什么是大布局,什么是大设计,什么是小设计。还是回到前面那个HelloWorld的例子,起初的需求总是简单而清晰的。当用户登录一个网站时,网站往往需要给用户打一个招呼:“hi, XXX! ”。同时,如果此时是上午则显示“Good morning! ”,如果是下午则显示“Good afternoon! ”,除此显示“Good night! ”。对于这样一个需求我们在一个HelloWorld原创 2014-08-26 10:42:46 · 1451 阅读 · 2 评论 -
大话重构连载10:小设计而不是大布局
开车的朋友一定深有体会,驾驶汽车其实就是在不断矫正汽车行驶方向的一个过程。在整个驾驶过程中,你必须全神贯注地紧盯前方,通过方向盘不断矫正方向,否则即使行驶在直线路段也可能偏离车道。那些疲劳驾驶的司机,因为进入睡眠状态,无法再矫正方向,车辆就会越来越偏离航向。这种情况下,即使数秒钟的小盹,也能造成车毁人亡的严重后果。重构与驾车虽然属于完全不同的领域,但其道理是相同的。原创 2014-08-10 14:49:09 · 935 阅读 · 0 评论 -
大话重构连载9:大布局你伤不起
作为优秀开发人员,重构应当成为一种习惯,自然而然地运用重构的开发模式,自然而然地在优化和调整我们的代码。它首先要求我们掌握重构的开发模式,就是“小步快跑”的开发模式,运用“两顶帽子”的设计顺序,去开发我们的程序。但作为重构初学者来说,这并不容易,即使你已经从业很多年。原创 2014-08-04 10:19:22 · 1063 阅读 · 0 评论 -
大话重构连载8:盘点我们的重构工具箱
下面我们来盘点一下系统重构工具箱里都有什么,也就是看一看系统重构到底都有哪些方法。系统重构总是在不同层次上调整我们的代码,因此重构方法也就分为了多个层次。从总体上看,重构方法分为以下几个层次:方法的重构、对象的重构、对象间的重构、继承体系间的重构、组织数据的重构与体系架构的重构。原创 2014-07-27 22:11:05 · 985 阅读 · 0 评论 -
大话重构7:重构是一系列的等量变换
毫无疑问,系统重构是一件如履薄冰、如坐针毡、你必须时时小心应对的工作,你就像走在钢丝上的人,每一步你都必须要保证正确,一个不经意的失误就可能让你万劫不复。尽管如此,只要你掌握了正确的方法,即使站在钢丝上也能如履平地,而这个正确的方法,就是那些被证明是正确的重构方法。说了那么多,你一定开始好奇,系统重构到底都是一些什么方法呢?行了,我也就不卖关子了,我们来看看重构方法工具箱里都有些什么东东。原创 2014-07-22 09:01:30 · 1096 阅读 · 0 评论 -
大话重构连载6:一个真实的谎言
经过前面的一番讲解,相信你已经对系统重构有了一些初步的认识了。一切的一切仿佛在告诉我们,系统重构总是与需求变更无关。但此时,我不得不告诉你这是真实的谎言。我们的软件系统总是处于一种变化之中,并且往往是一种由浅入深、由易到难的过程。但是,当系统复杂程度发生变化时,我们应当及时调整我们的设计,来适应新的变化。然而我们没有做到这一点,所以我们的系统维护变得越来越困难。要解决我们的问题必须通过系统重构去优化我们的程序,使之重新适应业务需求。毫无疑问,需求变更才是我们去重构的主要动因。然而......原创 2014-07-22 08:54:44 · 906 阅读 · 0 评论 -
大话重构连载5:软件修改的四种动机
软件,自从被我们开发出来并交付使用以后,如果它运行得好好的,我们是不会去修改它的。我们要修改软件,万变不离其宗,无非就是四种动机:1. 增加新功能;2. 原有功能有BUG;3. 改善原有程序的结构;4. 优化原有系统的性能[1]。第一种和第二种动机,都是源于客户的功能需求,而第四种是源于客户的非功能需求。原创 2014-07-09 11:28:29 · 1089 阅读 · 0 评论 -
大话重构4:大布局与小步快跑
以往我们在重新设计一个系统时,总是喜欢大布局。全面地整理系统需求,全面地分析系统功能,再全面地设计系统、开发、测试。这样一个过程往往会持续数月,花费大量的工作量。但是,不到最后设计出来,谁都不知道会不会存在问题。这就是“大布局”的弊病。正因为如此,软件大师在讲述系统重构时总是强调,系统重构应当避免大设计,而应当尽量采用一个一个连续不断的小设计。这就是我们所说的“小步快跑”的设计模式。原创 2014-07-07 17:51:56 · 1167 阅读 · 0 评论 -
大话重构连载3:在保险索上走钢丝
当我们开始系统重构的时候,不是着手去修改代码,而是首先建立测试机制。不论什么程序,只要是被我们修改了,理论上就可能引入BUG,因此我们就必须要进行测试。既然是测试就必须要有一个正确与否的评判标准。以往的测试,其评判的标准就是是否满足业务需求。因此,测试人员往往总是拿着需求文档测试系统。与以往的代码修改不同,重构没有引入任何新的需求,系统原来什么功能,重构以后还是这些功能。因此,重构的测试标准就只有一个,就是与之前的功能完全保持一致,仅此而已。原创 2014-07-02 19:16:31 · 904 阅读 · 0 评论 -
大话重构连载2:什么是系统重构
前面我们提到了,面对软件工业时代的到来,我们的软件企业陷入了一种更深的迷茫之中,一种“后有追兵,前有悬崖,进退两难”的境地。后有追兵:面对维护了数十年之久的大型遗留系统,我们到底改还是不改?不改,面对越来越多的需求变更,我们维护的成本越来越高,变更变得越来越困难;面对不断涌现的新技术,使我们的系统显得越来越丑陋与落后;面对越来越多的竞争者,使我们面临着被市场淘汰的风险。前有悬崖:原本运行得好好的软件系统,凑合一下还可以运行几年。一不小心改出问题了,企业立马就歇菜儿了,面对大量的用户投诉,企业四处救火,竞争对原创 2014-06-29 04:27:44 · 1336 阅读 · 0 评论 -
大话重构连载:遗留系统——软件工业时代的痛
我常常感到幸运,我们现在所处的是一个令人振奋的时代,我们进入了软件工业时代。在这个时代里,我们进行软件开发已经不再是一个一个的小作坊,我们在进行着集团化的大规模开发。我们开发的软件不再是为某个车间、某个工序设计的辅助工具,它从某个单位走向整个集团,走向整个行业,甚至整个社会,发挥着越来越重要的作用。一套软件所起到的作用与影响有多大,已经远远超越了所有人的想象,成为一个地区、一个社会,乃至整个国家不可或缺的组成部分。慢慢地,人们已经难以想象没有某某软件或系统的生活和工作会是怎样的。这就是软件工业时代的重要时代原创 2014-06-18 10:15:24 · 1850 阅读 · 0 评论 -
我的新书终于要出来啦
我的新书《大话重构》终于要出来啦!这是一本讲咱程序员应该怎样开发高质量代码的书,它用大量精彩的故事,讲解高质量的代码是怎样一步一步开发出来,其设计的过程、心理的历程、遇到的问题、解决的思路……这是一本解惑的书,它通过故事向你阐述许多深邃难懂的设计难题;这又是一本故事会,它将那些枯燥的技术问题通过故事娓娓道来。它让你告别游击队转变为正规军,远离劣质代码走向精妙设计,真正明白专业级的软件开发是怎样的,真正明白重构是怎样一步一步进行的。你也许会问,设计高质量的代码跟重构有什么关系呢?为什么你一边在谈高质量的代原创 2014-04-07 16:30:44 · 918 阅读 · 4 评论 -
大话重构连载首页
《大话重构》这本书是我写的第一本书,从今天起我将通过连载的形式逐渐跟大家分享。原创 2014-06-18 10:01:23 · 2630 阅读 · 0 评论 -
中国软件业真的到了该反思的时候了
中国五千年文化造就了我们诸多的性格,其中之一就是好大喜功,这尤其反映在中国的软件产业。不错,我们确实拥有数量巨大的网民,拥有无与伦比的庞大市场与用户需求,但这并不足以让我们的步入世界领先行列。在巨大的市场优势面前常常让我们有些迷离,有些飘飘然,有些盲目地民族自豪感,喊出诸如“赶英超美”的口号。然而,客观地讲,我们现在却是差距巨大。也许你觉得我这话有些崇洋媚外,但静下心来仔细分析我们自己设计的软件,我们注重了软件质量了吗?我们在如履薄冰地进行每一次设计了吗?我们的每一个系统都在编写高质量的代码了吗?也许每个原创 2014-04-07 12:22:50 · 1316 阅读 · 3 评论