现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

范钢:《大话重构》作者谈重构

2015-10-04 21:25 工业·编程 ⁄ 共 8281字 ⁄ 字号 暂无评论

范钢,航天信息股份有限公司架构师,《大话重构》作者,哈工大软件工程硕士,软件架构及重构的客座讲师。从需求分析、软件开发到项目管理、架构设计都有丰富的从业经验。大型遗留系统改造专业户,长期关注大型业务系统的品质保证、防止腐化以及技术改造等困扰软件企业的问题,进而提出了许多实用而有效的解决方案,在遗留系统优化与改造方面有丰富的经验。

范钢说,越是大张旗鼓地重构越容易失败,越是从实用角度出发、从小处去重构越容易成功。

CSDN:请先介绍下自己以及所从事的工作

范钢:我是70年代生的人,在IT行业也算是一个老兵了。我这些年一路走来,从最初做小弟,然后当需求分析员、设计师,再后来带着一帮小弟全国各地做项目。

掐指一算去过的地方还真不少:

  • 2006年,我们跟美女在湖南的凤凰古城待着;
  • 2008年,在清晨静谧的云南抚仙湖里泡澡;
  • 2009年,沐浴在西安古城的暮鼓晨钟之中;
  • 2010年去了长白山天池;
  • 2011年上西藏布达拉宫,还去了圣湖纳木错;
  • 2012年,偶们又在青岛喝啤酒、吃海鲜,享受静谧的青岛之夜;
  • 2013年,上天下第一险华山论剑去了。

丰富的经历使我能够站在不同的角度、比较全面地思考软件研发方方面面的问题。

CSDN:作为一个IT老兵,你经历过哪些技术变革以及学习过哪些语言?哪些经历令你印象深刻?

范钢:记得90年代末我还在学校读书的时候,用的都是面向过程——诸如C、Fortran的编程语言。后来是VB,那时每天废寝忘食研究VB的日子仿佛就在昨天。世纪的钟声敲响以后,我们都在使用PowerBuilder开发项目。那时你能想象1-2个人就能完成一个项目吗?完成需求分析以后就开始数据库设计,然后一天就可以设计N多DataWindow,一个月就能完成一个项目的研发。

我经历的第一次重大的变革来源于2004年,当我从老家信心满满地来到北京时,突然发现我过去擅长的一切都变得无用了,我必须从头开始,那是一种对未来无比的恐惧与无助。我不得不从头开始学习Java,学习J2EE,学习三层结构。后来eclipse出来了,放弃了JBuilder;Spring Frameworks出来了,放弃了EJB……现在,正在经历由传统架构转变为互联网与大数据的大变更中。

CSDN:你是如何看待这些变革以及对应的语言?

范钢:经历那么多变故,发现变故不可怕。这个行业的特性就是这样,总是在变。与其迟疑不定,不如从心里去接受它,然后先人一步去变,它会给你更多的淡定与自信。

如今,我开始放弃Java学习Scala。我突然发现,所谓技术,有时候就像一部时尚大片。10年前,我们不得不放弃那些function开始面向对象编程;经历10年的轮回,如今我们开始放弃笨拙的对象,进行函数式编程。但经过10年我们是不是又回到了原点呢?其实不是的,我们的技术开始在螺旋式地盘旋上升。

CSDN:每次的技术变革基本都要求你从头开始,在快速学习以及心态调整上有什么和大家分享吗?

范钢:与其被动地惧怕变革,不如欣然地去面对变革。多看书、多上CSDN看博客、刷论坛,就会让你的头脑总是保持新鲜。你应当保持一颗好奇的心,对什么新技术,总想一探究竟。Redis出来了,用一用;Spark出来了,学一学。你不必样样精通,但必须见识广博。还有就是,要学就学主流的,非主流的要学会放弃,做一个技术界的时尚达人。因此,有一些圈子,认识一些牛人还是蛮重要的。他们不一定能给你解答难题,但却可以给你最新的资讯,让你始终站在技术最前沿,去学习最该学习的东西,从而让自己也成为一个牛人。

CSDN:从业这么多年,什么的项目对你帮助最大?

范钢:要回答这个问题,大家先思考一下另一个问题:如果有一个人,一生都很顺利,没有经历什么挫折,做什么成什么,那么这是“完美人生”吗?我认为恰恰相反,这不是完美人生,他的缺憾就在与他没有经历失败。我们不希望失败,但对于每个人来讲,失败往往给你的帮助是最大的。“常在河边站哪有不湿鞋”,谁没有经历过失败的项目,然而正是这些失败的项目对我帮助才是最大的,它让人一夜从男孩转变成男人。最关键是,不要去遗忘和逃避失败,而是要正视与总结失败。

2011年经历了我职业生涯最大的打击,陷入了人生最大的低谷。由于没有做好项目管理与客户沟通工作,被撤销了项目经理职务。我们每个人忘掉过去的痛苦与失败都是容易的,但要真正面对失败去分析与总结,才是勇敢与不断进步的表现。因此从这年的9月开始,我陆续发表了系列文章《一次迭代式开发的研究》,站在更加实践的角度去探讨项目管理的风险与应对的措施。从此一发不可收拾,写了不少脍炙人口的系列文章。

CSDN:对重构,大家的理解可能都有所不一样,你对重构是怎么理解的?

范钢:有人认为重构是阳春白雪的高端玩意儿,我却认为它是咱寻常D丝的编程利器,让设计方面乏善可陈的我们,也能写出高质量的代码;有人认为重构是必须到无药可救时才能放出来的终极大招,我却认为它是一开始编程就应当养成的编程习惯,编程→重构→优化,不断循环这个过程才是优秀程序员必备的素质。项目经理总把重构当成洪水猛兽,但它真的是项目经理的亲密伙伴,它让软件项目从恶性循环走向良性循环,重新焕发生机。

总之,只有学好重构,才能成为一名真正优秀的程序员和技术管理人员。

CSDN:进行重构,应该遵循什么原则?

范钢:重构不是大家想象的那种暴力改代码,也不是通常认为的那种推倒重来,重构是要按照一定的科学方法与步骤进行。

  • 首先,在修改代码时应当运用重构方法进行重构,这些方法都是一个一个的等量变换,它能保证重构前与重构后的程序代码功能完全一致,从而实现安全重构;
  • 其次,重构是从原有代码开始,一小步一小步的修改代码,每改一次10-30分钟,然后运行调试,通过测试用例进行验证,这个过程被称为“小步快跑”;
  • 另外,重构是不改变软件的外部行为的,所以可以在重构前先建立测试用例,能跑通原程序,那么在以后的重构过程中,能够跑通同样的这些测试用例,重构就是正确的,以此来验证重构的正确性;

记住,重构是不可能一步到位的,应该从简单开始,一步一步改造,一点一点优化代码。

CSDN:有人说,重构应避免过度思考,你对这句话怎么看?

范钢:是的,重构应避免过度思考,这里的过度思考就是,将几步并为一步,在某一步骤的重构中思考过多,过快地进行重构。

大家知道,不论做什么事情,都应当遵循一定的章法来做事,而那些自作聪明、将几步并为一步的做法常常会适得其反,重构也是这样的。“小步快跑”的开发模式,就是要求我们在重构过程中,一步一步、循序渐进地进行重构。在每个重构周期中,不要想得太多,仅仅只采用一个重构方法来进行重构。这样做一方面容易检验我们重构过程的正确性,一旦重构出错,可以快速定位问题原因,解决问题,恢复正常,提高开发的效率;另一方面保证我们思路的清晰,避免我们因思考得过多、过于复杂而顾此失彼、带来新的BUG,给重构工作带来风险。

一次只采用一个重构方法,这说得容易,但常常在实际工作中,在运用这个重构方法时,同时想到了别的重构,这该怎么办呢?我们在完成了此次重构以后,很可能就忘掉了那个重构!这时,一个好的习惯就是拿着一个小本随时记录下这灵光一现的思路,然后在完成每次重构以后不断去check out那些记录。这样,既避免了过度思考,又保证这些想到的重构步骤在日后都能够及时回忆并予以完成。

CSDN:其实重构是一个事后补救措施,一旦重构就需要浪费大量时间和精力成本,因此你认为开发者应该养成什么样的习惯才能尽量地避免重构。

范钢:正所谓“积少成多,金石为开”,我们需要浪费大量时间和精力成本去重构,是因为我们欠的技术债太多了。如果我们每次编程都是遵循着“编码→重构→优化”的步骤去做,或者每次需求变更时都按照“两顶帽子”的思路先重构代码以适应新的需求,再变更,重构真的就不是一个事儿。但是现在我们已经欠了那么多债了,怎么办呢?是不是我们就应当大范围的大搞重构呢?其实往往不是这样的。

按照我的经验,越是大张旗鼓地重构越容易失败,越是从实用角度出发、从小处去重构越容易成功。什么叫“从小处出发”,就是着手思考和优化你经常要调整的代码,总在修改并且越改越别扭的代码。从函数级别、从对象级别,用最小的代价去重构你最急迫需要优化的代码,你越容易取得成功。

CSDN:重构并非万灵药,你认为在什么情况下不应该去重构?

范钢:重构是一种习惯,当我们在编写代码时应当采用“小步快跑”的方式,先用最简单的方式让代码跑起来,然后遵循着“编码→重构→优化”的方式一点一点往里面添加新的功能和代码;当需求变更时,运用“两顶帽子”的方式先重构再变更。但所有的重构都是面向着那些我们在不断变更和调整着的代码。但如果我们的某些代码没有发生变更,运行得好好的,我们为什么要去重构它们呢?我们还是省省力气吧,千万别过度重构。

CSDN:有人说重构是架构师、技术大牛的事,和普通程序员无关,对此你怎么看?

范钢:重构是架构师、技术大牛的事,也是普通程序员的事,只是站在的层次不同。重构分为代码级别的重构、组件级别的重构与系统级别的重构。普通程序员关注得更多的应当是代码级别的重构,它让我们可以去优化我们的函数、方法、类的设计;架构师与技术大牛关注的则是系统级别的重构,它考虑的则是如何系统地去调整软件的架构,即分层结构与技术框架,从而适应未来市场的变化与技术的革新。

那么,不同级别的重构都应当怎样做呢?这些在我的新书《大话重构》中都有所探讨。

只要有好的编程习惯,小白也能写出高质量代码

CSDN:你怎么看待高质量代码和重构之间的关系,为什么?

范钢:要弄清这个问题,让我们先弄明白什么在制约我们高质量的代码。过去我们有一个误区,就是认为高质量的代码设计要在编码之前做很多的设计,考虑很多可能的变更,做出很多灵活的设计。然而,我们不是先知,我们不知道未来会有什么样的变更,因而我们走向另一个极端——过度设计。

其实我们真的不用那么焦虑未来的变更,因为我们有重构。用最简单而清晰的设计实现当前的功能就是高质量的代码。然而,为什么我们的代码经过几轮的变更以后质量就开始下降?那是因为我们的软件在随着需求的变更而变得越来越复杂。简单软件有简单软件的设计,复杂软件有复杂软件的设计。当简单软件随着需求的变更变为了复杂软件时,我们还在简单软件的设计上强行添加代码,软件质量就开始下降。因此,采用“两顶帽子”的方式,先重构代码以适应新的需求,再变更,就能让我们的软件重新回复高质量的代码。因此,我认为,重构是实现高质量代码设计的一个捷径。

CSDN:那高质量的代码如何实现呢?

范钢:要实现高质量的代码其实很简单,就是养成一种好的编程习惯,即使刚毕业的小白也能做到的:

首先,在编写新的代码时,应当学会采用“小步快跑”的编程方式。简单来说就是,先从整体上进行一些设计,忽略掉很多分支与细节,用最快速而简单的方式编写第一个版本,让程序迅速跑起来。然后一小步一小步地重构代码,不断往程序中添加功能,添加分支与判断,不断完善与丰富功能,运行、测试、优化。这样,系统就像小树苗一样一点儿一点儿成长,最后变为参天大树。在这个过程中,我们总是能够运行、能够验证正确性、能够不断优化,就能保证代码的高质量。
其次,当需求变更到来时,一定不能就着原有的程序结构简单的往里面添加代码,这是代码退化的罪恶之源。根据需求分析现有的程序结构,对其进行调整,该增加可扩展点的增加可扩展点,该代码复用的将需要复用的代码提取出来。只有当我们正确完成了代码重构以适应新的需求以后,再实现新的功能,才能真正让需求变更不会带来代码的退化。这个过程就是重构中所说的“两顶帽子”。

正是因为有了重构,从大的环境上进行了保证,才能让我们在今后的编码与变更过程中,该扩展的扩展,该复用的复用,该解耦的解耦,再辅之以相关设计模式与设计原则的学习,从而真正实现高质量的代码编写,让刚毕业的小白不再是项目经理的痛。

CSDN:能对“小步快跑”的编程方法举几个例子吗?

范钢:“小步快跑”的编程方法,是一种高效的编程方法,它摒弃了那种“完备的设计→完备的编码→完备的测试”这种近乎于瀑布式的开发模式。“小步快跑”的编程步骤通常是这样:

  1. 忽略掉所有的细节与分支,用最简单快捷的方式完成主流程的编写,让程序快速跑起来;
  2. 以重构的方式不断往程序中添加新的功能,每次添加新的功能都应当足够短小而可以快速实现,从而通过测试快速检验新增的功能;
  3. 不断往复步骤2,直到完成开发。

为了说明这种编程方法,让我们用实际工作中的一个案例来进行讲解吧:

为了让案例尽量贴近工作,又不给大家带来业务知识的障碍,我们来看看一个数据推送程序的实现过程。该程序的需求就是将一个数据库中的数据推送给另一个数据库,一方面应当能够高效处理大量数据,让推送方与接收方有效解耦,另一方面应当能够实现字符集转换、运行过程的监控以及方便快捷地定义新的推送接口。当你接到这样一个需求的时候,你是怎样去分析和设计的呢?

显然,这个简单功能所要达到的预期目标很多:高效处理大量数据、让推送方与接收方有效解耦、实现字符集转换……要一一实现确实需要很多的设计。但采用“小步快跑”的方式,起初你并不需要想那么多。首先从宏观上制定出技术方案,即先采用一个高效的方式导出数据文件,再用一个高效的方式导入到目标数据库。制定出这样一个技术方案以后,我们就可以动手编程了。

动手编程时,不要想那么多,首先编写一个简单的导出程序,SQL是固定的,参数也写死。就一个目标:能跑通,第一个版本就形成了。

在此基础上开始我们“小步快跑”的重构之旅了(注意:每完成一步都要测试与验证):

  1. 编写一个模板,让SQL是可变的,参数也可以配置;
  2. 在模板的基础上,让SQL与参数都配置在元数据表里,通过配置这些表就可以快速地定义一个一个的数据推送接口;
  3. 开始编写导入程序,在编写时发现可以大量复用导出程序的代码,故而重构导入程序,将公共部分抽取接口或工具类,从而实现代码复用;
  4. 完成简单的导入程序并跑通后开始改写,通过模板与元数据实现推送接口的可配置;
  5. 实现各个过程的日志编写,以及目标数据库的对账校验功能;
  6. 实现各个过程的异常处理,以及系统级的异常信息采集;
  7. 完善各个部分的代码命名与注释;
  8. 重新思考与调整各个功能的分层与解耦。

CSDN:你对需求分析怎么看?你后来还提出了“客户需求可行性分析”理论,能大概介绍其关键点吗?

范钢:这些年做了那么多软件项目,有成功的、有失败的,真的切身感受到,需求分析的成功与否,非常关键地决定了一个项目的成功与否。无数令人绝望的项目都是始于不到位的需求分析。然而,在实际工作中,我们的需求分析工作既低效又无所适从。通过这一系列的文章,我点出了需求分析工作问题的核心,那就是被动式的需求分析,即客户说什么就是什么,一切都以客户说的为准。客户往往是非技术的,因此客户提出的需求往往也是非常理想而难以实现的。用这样的需求去指导开发,结果可想而知。

正确的做法应当是主动式的需求分析,即跳出客户需求的本身去主动学习与理解客户的业务领域,分析客户需求背后的动机,从而站在更加深刻的角度去理解客户的需求,然后结合技术实现去分析客户需求隐藏的问题,这就是所谓的“客户需求可行性分析”,即分析客户需求是否可行。最后,站在客户的角度去探讨其中的问题,同时提出更加可行的方案。

这里的关键问题就在于我们对客户业务领域的理解到底有多深。我们对业务领域理解得越深,我们对客户需求的理解就越深,分析的问题也就越深,与客户探讨的过程中就越能被客户认可,从而提出为客户认可与接收的技术方案。这样的方案,既准确表达了客户的需求,又可以在技术上是可行的。按照这样的方案设计开发软件项目,才能真正有效地规避需求方面的风险。这种思路在实践中得到了许多的成功,并且让无数的网友脑洞大开。

CSDN:什么是过度设计?应该如何避免?

范钢:过度设计,是因为设计者担心日后的变更,担心日后变更时现有设计无法应付,因而做出的当前需求不太需要的可扩展点或者一些灵活设计。这些设计虽然可以应付日后的变更,却是要付出成本的,它会加大软件的复杂度,降低系统运行效率。如果这些设计日后用上了,这种成本是值得的,但如果没有用上,你不仅没有获益,还需要为之买单,其实是非常不划算的。所以,在我看来,任何事情只有化繁为简,我们才能做得更好,才能从容应对。

不论你在设计还是重构,都不要想得太多,想得太长远,因为你不是先知。“活在今天的格子里,做今天的事儿”。那么未来变更了该怎么办呢?当变更时,运用“两顶帽子”,先重构系统以适应新的需求,再变更,那么什么状况你都能应付了。到那时,所有那些可扩展点与灵活的设计,都是后移到变更时才做出,就可以有效避免软件的过度设计。

没灵感时,请放空自己

CSDN:在平常工作过程中,是否遇到一些难缠的问题,导致一时半会无法解决的,这个时候,你们都是如何应对,重新焕发“灵感”? 

范钢:在IT这个行业所有的人都很勤奋,这是我们都优点。但我希望我们要做的不仅是十分勤奋的程序员,还应当是充满智慧的程序员。一个充满智慧的程序员,不应当是那种埋头苦干的程序员,而是将更多的时间用来思考那些精妙设计的程序员。

因此,当我在平常工作中遇到了难缠的问题,一时半会无法解决、想不清楚、拿不出好的方案的时候,我往往的选择是放下手里的活儿干点儿别的。倒杯水、喝个咖啡、散散步,抑或是写个文档、做点儿别的事情。当你将手里的活儿、现有的思路忘得一干二净的时候,再重新回来工作,很可能就会迸发出新的火花,产生新的思路,冒出新的解决方案,重新焕发出灵感。很多创新的设计就是这样出来的。记住,在IT这样一个充满创新与智慧的产业里不要去做一个埋头干活儿的工兵。

CSDN:请给我们程序员朋友推荐重构、架构方面的书籍吧?

范钢:重构方面最经典的毫无疑问就是那本《重构,改善既有代码的设计》,它是软件重构的理论基础与入门书籍。这本书虽然阐述了“重构”这样一个重要的概念,却不能帮助我们很好地在工作中去实践,而这正是所有重构者最头痛的事情。正因为如此,看一些重构实践的书籍对大家是很有帮助的,Robert C Martin写的《代码整洁之道》和《敏捷软件开发:原则、模式与实践》在代码级别的重构方面都是不错的选择,而埃文斯写的《领域驱动设计:软件核心复杂性应对之道》则在系统级重构方面可以给我们很多的借鉴。此外,《大话重构》是我奉献给大家的一本呕心力作,也能给大家一些帮助。

软件架构方面,温昱写的《软件架构设计》、人邮出版的《恰如其分的软件架构》和马丁·富勒的《重构与模式》都是不错的书籍。作为一个优秀的架构师,不是仅仅技术好就可以了,而是要拥有很好的大局观与前瞻性才可以。这些书籍都可以很好的拓展你的思路与视野,从而站在一个更高的角度看待一个系统。

CSDN:对于当下的中国软件产业,你有什么思考或建议吗?

范钢:当下的中国软件产业,用“浮躁”二字来形容一点儿不为过。人们追逐新技术、开拓新市场,这毋庸置疑。但是,在尝试一个一个的新技术,推出一个一个的新产品的同时,很少有人真正去关注那些软件内部的质量。那些管理者不关注软件质量,他们关注的是新产品的开发进度;那些有经验的程序员也不关注软件质量,他们虽然掌握着丰富的经验与软件技术,却带头写着糟糕的代码,让刚毕业的新生们情何以堪。缺乏卓越品质追求的中国软件产业,就像一个缺乏深厚内力的武者,很难在激烈竞争的软件市场上走得更远,走得更坚实,这就是中国软件产业的现状。

因此,作为中国软件产业中有责任的一员,我们应当更加关注软件的品质,更加关注软件设计这门技术。我们应当将软件设计当成一门艺术,每一次编程都应当去精雕细琢。只有软件品质上去了,我们的软件企业才会走出小作坊,在这个激烈竞争的产业中占据一席之地。而“重构方法”、“小步快跑”、“两顶帽子”则是我为大家找到的,快速实现这个目标的最佳实践与有效捷径。

CSDN:最后想问下你:是什么因素促使你现在进入大数据分析领域?

范钢:众所周知,软件产业是所有产业中变化最大的一个产业,每隔三、五年就会完成一次改朝换代。在我看来,这个产业未来发展的趋势必然是互联网、大数据与移动应用。这三个趋势得其一则得天下。在我以往的项目经历中,在基于数据分析的防欺诈与风险控制方面,具有丰富的经验。这些经验为我现在进入大数据分析领域打下了坚实的基础。如今我尝试进入企业大数据征信领域,期望在这个领域中闯出一番新的天地。

给我留言

留言无头像?