只接受发布货源信息,不可发布违法信息,一旦发现永久封号,欢迎向我们举报!
1064879863
16货源网 > 餐饮行业新闻资讯 > 软件开发 >  为什么软件开发需要重构?


为什么软件开发需要重构?

发布时间:2019-05-23 05:47:34  来源:网友自行发布(如侵权请联系本站立刻删除)  浏览:   【】【】【
「重构」并不是完全打翻重来,最开始的设计也并非一无是处。软件开发是一个过程,软件使用的人群、环境都可能在进行中发生变化,当初设计中的一些假设、条件都会变化,这就需要根据新的状况做出调整。「重构」是代码
为什么软件开发需要重构?
  • 「重构」并不是完全打翻重来,最开始的设计也并非一无是处。
  • 软件开发是一个过程,软件使用的人群、环境都可能在进行中发生变化,当初设计中的一些假设、条件都会变化,这就需要根据新的状况做出调整。「重构」是代码层面的「重设计」,代码是软件的实现方式,设计做出调整,代码当然也要调整。
  • 「重构」也是对原有代码的完善,消除代码中的腐臭味,让代码更健壮、效率更高、更易维护。这是软件开发的规律决定的,没有人能一次写出完善的代码。
我的答案可能跟重构没有任何关系,关于程序开发,我个人认准的两条准则是“迭代”+“DRY”,从这两条准则出发,重构就是通过不断迭代的过程调整程序的结构,消除Repeat Yourself的代码和构建。 举个例子。假设构建一个复杂系统需要考虑10点。由于人本身的局限,你肯定会做错其中的6点,当然这6点并不影响第一版的发布。然后,你如何修正这6点?
  1. 你不能重写系统。因为重写系统你还会做错6点,虽然可能是不同的6点。
  2. 你不能在增加系统功能的同时修正这6点,因为增加一个功能,就会再增加比如说5点要考虑的东西,这个过程中你又会做错3点。
  3. 当你不增加新功能,又试图修复这6点中的某一个或者几个,这个过程就是『重构』。
  4. 重构并不能保证不会毁掉你原本做对的4点,但是你起码可以肯定这个错误是因为你的重构造成的而不是别的原因(比如第2种做法里新增加的那5点)。而且这也是鼓励你在第3种做法里尽量只修正一个错误。
  5. 你永远达不到完全做对10点,即使你有无限的时间重构。而实际上你的重构永远在和添加新功能竞争资源。
  6. 由于第5点,你不要无缘无故的重构,除非需要增加新功能。但是由于第4点,又不能和增加新功能同时进行。

当人类文明的代码积累到一定程度,我们就不再需要写新代码(或者只需要写胶水代码即可)。那时的程序员会被称为考古程序员(因为总是在重构已有代码)。参考《天渊》。 1.需要重构,看着大量重复的代码、不优雅的设计等等,真的想把他改掉,怕留下来丢人。
2.愿意重构,重构需要投入时间和精力,这需要我们的决心。
PS:最近做的一个项目就是如此,同时也是自己做的第一个项目,很纠结。 个人经验,没有任何建议。
一般是迁移的多 , 全部换另一种方式(编程语言,数据库等)
重构的少 (同一种语言等)个人比较同意@冯东 和 @李申申 的回复,补充一下,我认为,重构这种事情对于还有生命价值的软件而言,就是必需的。这一点我觉得可以类比人类和任何一种有生命的动物。

任何一种生物都不是完美的,但它(他、她)却可以在一定程度上适应环境的需求,但是适应的并不完美。所以才需要重构这种不断地“新陈代谢”和“进化”,保持这个物种在大自然中的竞争力。也只有被淘汰的物种才不需要新陈代谢和进化。

具体的重构的要素,其实软件工程之类的书籍中都有谈到了,上面的同学也谈到了很多,这里就不重复了。什么是重构呢?重构就是以一种可控的方式,一小步一小步地调整当前的设计。 重构的原因在于在现有的设计中已经无法优雅地实现新增的需求。

原先的设计是建立在对问题空间的认识上,随着时间的推移,对问题的认识就会产生变化,原有的设计就要进行修改。认识的改变在于:
  • 人对问题的理解总是由零碎,片面、表面、粗略到整体,全面,深刻,精准的。
  • 现实世界的问题本身也在无时无刻地变化中。

作为一种修改设计的方法,重构是建立在面向对象程序设计,单元测试和重构方法的基础上的。
  • 单元测试保障了每一小步的修改都能够通过单元测试进行验证,不影响系统原有的功能。
  • 重构方法,包括 抽取方法, 将属性或方法上移至父类,或下移至子类,抽取接口,引入中间人,引入参数对象等等。
重构,而不是重写,降低了对设计进行修改的风险,也就降低了设计阶段产生的缺陷的修改成本,也就减少了过度设计的产生。在项目进入迭代早期,为了快速满足项目功能上的需求,在项目的扩展性,可维护性上会有折扣。
所以到了闭环内,需求相对固化的阶段,重构是在保证业务功能不变的情况下,进行可维护性,扩展性,健壮性的开发行为。为什么不去读martin fowler的重构一书呢?你回忆一下自己,当对母语的掌握程度逐渐熟练以后、当自己的词汇量逐渐增大以后、当对社会的理解加深以后,你会发现小时候说的话的思想很浅薄、表述水平又很低。只要有机会,你很愿意重新说一遍

一个人需要20年才能极其熟练地掌握自己的母语和(大致)理解社会;一个程序员最起码也要20年才能走完对应的道路我并不想说重构能够解决软件中所有的问题,它不是“银弹”。然而重构是非常有价值的工具,它是你可以用来很好地控制代码的“银钳子”。重构能够,也应该,被用来完成软件上的诸多目标。
重构能改善软件设计
重构使软件更易理解
重构有助于找到Bug
重构有助于提高编程速度

重构,企业级应用的圣经 这里有一系列讲重构的,共享下~~需求是分形,产品是分形,项目是分形,代码是分形。我们永远不可能精确完成,只能以迭代的方式无限逼近。代码重构,就是这迭代的一部分。正好最近在整理跟重构理论及发展相关的材料。

先上结论:其实软件开发并不一定需要重构

作为《重构》这本书的译者,我有一个观点:重构已死。当然这种“xx已死”的调调一听就知道是哗众取宠的。更加严格的说法应该是:《重构》书中所描述的、针对面向对象语言单一代码库的重构技术,是在一个独特历史背景下发展成型的产物;在当今的软件开发历史背景下,这种技术的适用范围正在变窄,且适用的问题域和解决方案都已相当成熟,因此不再有继续讨论的价值

=== 第一更:重构是(和不是)什么 (2016-01-02) ===

为了使接下来的讨论有一个可靠的基础,首先需要对“重构”(refactoring)这个词作一个明确的定义。按照《重构》书中的定义:

第一个定义是名词形式:

重构(名词):对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性,降低其修改成本。

“重构”的另一个用法是动词形式:

重构(动词):使用一系列重构手法,在不改变软件可观察行为的前提下,调整其结构。


上述定义中,第一个值得注意的关键词是“不改变软件可观察行为”。按照这个关键词,@冯东所说的情景就不是重构(当然,这还取决于他说的“做错”和“修正”如何定义,我假设“修正一个错误”意味着“改变软件可观察的行为”)。

第二个关键词是“重构手法”。一次重构之所以能成为一次重构,它必须遵循一定的重构手法,而不是随便调整。很多人在阅读这本书的时候只看前四章,真正动手改代码的时候根本不遵循重构手法,这样的行为也不是重构。我在这里采用一个较为严格的限定:只有遵循已经发表的重构手法时,才能认为是在进行重构。

第三个关键词是“软件内部结构”。这实际上是非常有玄机的一个词。玄机我们暂且按下不表,从Opdyke的论文到《重构》再到《修改代码的艺术》,重构理论的早期奠基作品谈论的都是单进程、单代码库的代码重构。因此,我倾向于将“软件内部”限定为“单进程、单代码库内”。

现在,当我讨论“软件开发是否需要重构”时,我讨论的是:

软件开发是否需要:
  1. 不改变软件可观察行为的前提下,
  2. 采用已经发表的重构手法
  3. 单进程、单代码库内的软件结构进行调整。
而我的观点是:在现代软件开发的环境下,越来越不需要。

=== 第二更:为什么重构 (2016-01-06) ===

以下内容出自《重构》第2.2节。我用粗体标注出了一些关键词,这些关键词将有助于我们理解重构技术背后的假设。

重构改进软件设计

如果没有重构,程序的设计会逐渐腐败变质。当人们只为短期目的,或是在完全理解整体设计之前,就贸然修改代码,程序将逐渐失去自己的结构,程序员愈来愈难通过阅读源码而理解原本设计。重构很像是在整理代码,你所做的就是让所有东西回到应该的位置上。代码结构的流失是累积性的。愈难看出代码所代表的设计意涵,就愈难保护其中设计,于是该设计就腐败得愈快。经常性的重构可以帮助代码维持自己该有的形态。


重构使软件更容易理解

所谓程序设计,很大程度上就是与计算机交谈:你编写代码告诉计算机做什么事,它的响应则是精确按照你的指示行动。你得及时填补“想要它做什么”和“告诉它做什么”之间的缝隙。这种编程模式的核心就是“准确说出我所要的”。除了计算机外,你的源码还有其他读者:几个月之后可能会有另一位程序员尝试读懂你的代码并做一些修改。我们很容易忘记这第二位读者,但他才是最重要的。计算机是否多花了几个小时来编译,又有什么关系呢?如果一个程序员花费一周时间来修改某段代码,那才关系重大—如果他理解你的代码,这个修改原本只需一小时。


重构帮助找到bug

对代码的理解,可以帮助我找到bug。我承认我不太擅长调试。有些人只要盯着一大段代码就可以找出里面的bug,我可不行。但我发现,如果对代码进行重构,我就可以深入理解代码的作为,并恰到好处地把新的理解反馈回去。搞清楚程序结构的同时,我也清楚了自己所做的一些假设,于是想不把bug揪出来都难。


重构提高编程速度

我强烈相信:良好的设计是快速开发的根本──事实上,拥有良好设计才可能做到快速开发。如果没有良好设计,或许某一段时间内你的进展迅速,但恶劣的设计很快就让你的速度慢下来。你会把时间花在调试上面,无法添加新功能。修改时间愈来愈长,因为你必须花愈来愈多的时间去理解系统、寻找重复代码。随着你给最初程序打上一个又一个的补丁,新特性需要更多代码才能实现。真是个恶性循环。

从这几个重构的原因中,我们看到了下列几个(我在引文中加粗的)关键词,我们可以来分析一下它们背后隐含的假设:
  • 短期目的 => 编程时仅考虑短期目的是不好的,也就是说,代码库有比较长的生命周期。
  • 另一位程序员 => 在这个代码库上工作的人数会比较多,且人员的变动比较频繁。
  • 一大段代码 => 代码库的规模比较大。
  • 添加新功能 => 一个代码库承担多种责任。
所以从2.2节中我们不仅可以读到为什么重构,而且可以读出作者没有明言的假设:作者在谈论的是规模较大、生命周期较长、承担了较多责任、有一个较大(且较不稳定)团队在其上工作的单一代码库。当然所有这些都是相对度量,例如多少行代码算大、生存多长时间算长,没有绝对而清晰的界定。

那么接下来我们就要问:为什么重构技术有这样一些假设?这些假设是在什么样的时代背景下形成的?这些假设在今天的时代背景下是否仍然适用?如果这些假设不再适用,重构技术是否仍然适用?

=== 第三更:重构的时代背景 (2016-01-07) ===

可能令人吃惊:重构出现的时间相当早,比Java早,比设计模式早。William Opdyke的博士论文Refactoring Object-Oriented Frameworks(下载PDF)发表于1992年,这篇论文是重构理论的奠基之作。(BTW,Opdyke这位老兄相当牛逼,他的博士导师是GoF之一的Ralph Johnson。)那么在Java都还没出现之前,重构的早期玩家们玩的是什么语言呢?答案是“Smalltalk”,传说中的“Ruby之根”——好吧,跑题了,打住。《重构》的出版是1999年,所以基本上我们可以认为,重构是上世纪90年代浮现、并在本世纪头十年引起重视的技术。

于是我们要问了:为什么在世纪之交的这十多年里,规模大、承担责任多的单一代码库成为了主流?在一个代码库、一个进程里承载一个系统所有的功能,这并不是一个古而有之的做法。例如在一个典型的基于VxWorks的电信系统中,职责划分不是以函数、而是以进程为单位。即便在Sun推荐的J2EE架构(http://docs.oracle.com/cd/E19683-01/817-2175-10/deover.html)中,业务是分散在若干个EJB中的,每个EJB可以(尽管未必总是会)被部署为一个独立的进程,所以整个系统也不必(尽管仍然可以)存在于单一代码库中。

然而Sun推荐的J2EE架构并没有被广泛接受,反倒是以Spring为代表的“轻量级J2EE”最终成为了主流。我在《不敢止步》里讲到,“轻量级J2EE”的核心架构思想实际上就是Martin Fowler的分布式对象设计第一法则:
分布式对象设计第一法则:不要分布你的对象!

另一种风格则是Apache、Jon Tirsen、Rod Johnson 等开源先锋推荐的Martin Fowler 在PoEAA 里总结的:不要分布对象,在一个Java 进程里完成所有业务逻辑, 用集群解决单台服务器负载过重的问题。这种架构风格,再加上后来的“Shared Nothing Architecture”,实际上就把Web 应用简化成了一个单进程编程的问题: 不是“使远程调用变得透明”,而是根本没有远程调用。

这个架构风格的最大价值是让开发者可以在自己的桌面电脑上复制整个生产环境,从而能够快速修改并看到反馈。“在个人电脑上复制整个生产环境”这件事,只有当个人电脑的性能高到一定程度时才有可能的。在90年代之前,电信、金融、医疗、航天、军事等主要的IT用户,其生产环境是很难复制的。所以当时的软件开发过程必须是瀑布式的,因为修改之后看到效果的反馈周期太长,只好尽量提前把设计做好,开发一次成功。而90年代个人电脑性能的提升、尤其是奔腾CPU的广泛应用,使“在个人电脑上复制整个生产环境”成为了可能。

而轻量级J2EE则是在这个时间节点上的关键一触,把可能性变成了现实。如果将业务逻辑分布在多个进程中,就不可避免地需要运行多个Java虚拟机进程(甚至多个应用服务器进程),而这些——在当时的标准下——庞大的进程会耗尽当时大多数桌面开发电脑的性能,从而使反馈周期变长。

能够在单台个人电脑上复制整个生产环境,这个能力开启了整个敏捷软件开发的想象空间。测试驱动开发成为可能,持续集成成为可能,用户代表跟开发团队的紧密沟通才有必要,每天的站会、每周的迭代展示和计划会议在这个反馈周期的节奏下才有意义,注重对话的故事卡在这个节奏下才显得重要。单一代码库、单一进程、不分布对象、服务器农场式部署的架构风格,其目的是尽可能地保障在单台个人电脑上复制整个生产环境的能力,从而显著缩短反馈周期。

这就是重构技术走进主流视野的时代背景:摩尔定律使个人电脑堪堪具备足够的计算能力来复制整个生产环境,敏捷社区迫不及待地用轻量级J2EE架构使“复制整个生产环境”成为现实,在缩短反馈周期的同时也使单一代码库不得不承载整个系统的职责,从而使整个代码库变得庞大且职责不单一。为了在这样的代码库上继续快速的“修改-反馈”循环,对这样的代码库进行内部质量保障和改进的技术——测试驱动开发、持续集成、重构——才变得重要。

那么,十多年以后,我们所处的时代背景发生了哪些变化?这些变化是否会使重构技术变得不再重要?

=== 第四更:今天的世界 (2016-01-13) ===

今天的商业IT环境用一个词就可以概括:不确定。不确定带来颠簸和变动,不确定滋生怀疑和恐惧。而这种不确定,从丰田决定用大规模定制的产品来服务消费者的需求、而非仅仅提供某种功能开始,就已经注定了。当产品的目的是提供某种功能,功能的要求和达成的方式是相对确定的,不确定的比例相对较小;而当产品的目的是满足消费者的需求乃至提供良好的体验,人的不理性、不逻辑性就开始占据更大的比重,从而使不确定性的比例显著增加。Martin Fowler在《企业应用架构模式》里讲,所谓“业务逻辑”,实际上是“业务不逻辑”——因为这些业务规则根本不合逻辑,所以它们才需要特别地被提出、被讨论、被理解、被确认。这个洞见反映出当代商业IT环境的特征:现在的商业IT,越来越多地是在建模与迎合人的不理性、不逻辑性。在这个背景下,不确定性的剧增就是不可避免的。

当不确定性还不算太多的时候,对软件的要求是可维护性:需要加新的功能、需要修改旧的功能,能改得进去。这种“维护”(或者叫“演化”)实际上仍然是基于预测的。整个软件系统的大致方向已经被预测了,然后在此基础上谈演化。而当不确定实在太多的时候,对软件的要求就变成了可抛弃性。整本《精益创业》讲的就是这么一回事:你构建(build)的所有东西,都是为了度量(measure)某种数据从而学习(learn)——“学习”的定义是证实或证伪某个假设(hypothesis),而一旦假设被证伪,就要立即转向(pivot)。换句话说,你开发的所有软件,都应该做好很快被抛弃的准备。

如何获得可抛弃性?很简单:少写代码。一万行代码扔掉要伤心,一千行代码随时扔掉重新写。从轻量级J2EE的胜利开始,开源软件在商用软件领域成为了绝对主流,并展现出巨大的复用优势:基础框架越来越成熟,应用编程越来越倾向于用DSL描述业务领域,代码量越来越少。Spring已经呈现出这个趋势,Ruby on Rails及之后的框架更将这个趋势推向极致:开发者可以在最短时间内以最少代码量做出一个规规矩矩的软件。开发这样的业务软件并不需要多少设计,因为大部分设计已经蕴含在框架内。代码结构简单,代码量少,决定了这样的代码库烂也烂不到哪里去。而且本来就是以可抛弃性为目标设计的软件,它的生命周期预期也不会长到让代码质量能烂到哪里去。

但是总有些系统会成功,会向着更复杂的方向演化。然而这时系统的演化就未必要在同一个代码库中进行了。在这个阶段,软件的设计者应该能区分出较为稳定的领域模型与较为易变的用户操作。领域模型与用户操作两者变化的频率不同,实现的技术也不同,完全没有理由存在于同一个代码库中。同时,多渠道、尤其是移动渠道的兴起,是另一个推动领域模型与用户操作分离的动因:领域模型最好是运行在自己的进程中,向各种渠道提供服务,从而在不同渠道之间复用领域逻辑。

于是我们再一次有了“以多个代码库、多个进程承载一个系统”的诉求。而这一次,摩尔定律的发展、特别是虚拟化技术的发展,使得“多进程”与“在个人电脑上复制整个生产环境”不再矛盾。正如Sam Newman在《Building Microservices》中所说:
Domain-driven design. Continuous delivery. On-demand virtualization. Infrastructure
automation. Small autonomous teams. Systems at scale. Microservices have emerged from
this world.

在同一本书里,Newman也提到了可抛弃性(他称之为“可替换性”)的问题:
Teams using microservice approaches are comfortable with completely rewriting services
when required, and just killing a service when it is no longer needed. When a codebase is
just a few hundred lines long, it is difficult for people to become emotionally attached to
it, and the cost of replacing it is pretty small.

既然不必把整个系统塞进一个代码库、一个进程,那么自然可以让每个代码库、每个进程符合单一职责原则,做且仅做一件事。这样的一个代码库规模不会大(尽管未必像Newman所想的只有几百行代码),在上面工作的团队也会很小。这样的一个代码库,它的质量不会烂到哪里去;即使出现了质量腐化的迹象,在有必要的测试覆盖的前提下,即使不遵循严格的重构手法也足以优化其内部质量;即使——尽管相当不可能——质量腐化到了相当的程度,正如Newman所说,从头写过就是了。在这样的一个代码库中,《重构》书中所描述的严格的重构技术所能发挥的价值将相当有限。

=== 第五更:尾声,以及新的开篇 (2016-01-15) ===

简单总结一下前面讲的内容:
  1. 《重构》所介绍的重构技术,是在不改变软件可观察行为的前提下,采用已经发表的重构手法,对单进程、单代码库内的软件结构进行调整。
  2. 这种技术适用于规模较大、生命周期较长、承担了较多责任、有一个较大(且较不稳定)团队在其上工作的单一代码库。
  3. 十多年前,企业应用架构转向单一代码库、单一进程、不分布对象、服务器农场式部署的架构风格,其目的是尽可能地保障在单台个人电脑上复制整个生产环境的能力,从而显著缩短反馈周期。
  4. 现在,更高的不确定性使代码库生命周期显著缩短,领域驱动设计和虚拟化技术使每个代码库职责单一。因此,在今天的商业IT环境下,重构技术的价值大大降低。
或者,换回哗众取宠的调调,我说的是:十五年以后,重构已死
清晰地认识到“重构已死”这一现实很重要。因为这个认识会让我们开启一系列更为宏大、影响更为深远的讨论:
  • 虽然单一代码库的职责变得简单,然而整个IT系统的复杂度仍然在。这些复杂度以何种方式表现
  • 虽然单一代码库的内部质量不至于严重腐化,然而整个复杂的IT系统仍然有可能腐化。一个复杂系统会以何种方式腐化
  • Opdyke在他的论文中介绍了一组行为保持的修改手法,以这些手法对程序进行修改时,对程序外部行为的影响可以被控制在最小范围。在代码之外,这些行为保持的修改手法是否普遍适用
  • 测试驱动开发是重构的安全网。在无法使用xUnit的情景下,如何构建安全网
  • Kerievsky在《重构与模式》中指出,重构以设计模式为目标。在面向对象设计模式不适用的场景下,如何确定重构的终点
我的观点是,虽然《重构》书中所介绍的重构技术已经过时,然而对坏味道重构手法的总结和抽象将指导我们得出广泛适用的重构思想,这种思想将有助于识别和解决其它复杂IT系统中的内部质量问题。并且由于康威法则(Conway's law)的作用,这种思想也将有助于识别和解决其它复杂组织系统中的内部质量问题。

用哗众取宠的调调来说就是:重构已死,重构思想永生

也许我会就这个题目写一本书。但愿我能写出来吧。

以上。是哒,而且总会有傻逼的PM你妹的改需求,老大总是会催命一样,能不需要吗谢邀。

赶paper累了,答个题算是放松放松吧。

觉得以上都说得挺充分的,我就从另一个角度来说说重构吧。

在博士期间做过一个与重构相关的研究工作,我当时写过一些代码来自动分析开源项目库中的重构情况。思路也很简单,也就是提取开源项目的Git库中的各版本,然后逐项比较,通过版本间的代码修改来自动提取重构操作。我一开始的想法是准备找一些纯做重构的代码提交(commit)来进行分析,但意外是,像在eclipse这样的极其注重代码质量的项目中,除了像“重命名”这样的重构操作,几乎很难找到一次专门做重构的代码提交。基本的情况是,包含重构操作的代码提交确实不少,但这些提交都额外地包含了功能添加或缺陷修改的代码。就这次观察的结果而言,重构,就像部队行军中的“粮草先行”,它很少凭空无谓地产生,其发生,往往由代码中其他的“利益”所驱动。

虽然这个研究最后没有深入做下去,但结论却也具有一点启发性。我遇到过一些程序员同学,他们似乎追求着一种“代码的洁癖”。他们无法忍受代码的复制粘贴,对设计模式的使用津津乐道。其实,在实际开发过程中,项目的代码并不是用来欣赏的,更多的情况是给定了一个deadline,然后大家努力赶工完成任务。所以,在大多数实际情况下,重构的意义是保证让整体的代码结构不会对代码生产、维护和理解的效率产生负面影响。因此,重构应该只是写代码行为中的一个权衡决策而已。当现有的代码结构变得开始拖累后续的开发和维护时,无需刻意,重构自然而然成了一种势在必行的选择。反之,如果刻意对代码进行高度复用,反而会和重构本身的意义南辕北辙。从这个角度来说,将设计模式用得眼花缭乱也许只是对到处复制粘贴代码的一种矫枉过正,哪一个危害更大,其实,并不好说。毕竟,重构,如同生活中的很多事情,贵在自然嘛~简要回答下自己的感受,
毕竟代码是给人看的,重构一大作用就是让原先快速开发后的复杂代码变得简化,让人更好理解。
另外就是为了应对业务需求变化,让代码更好扩展。写代码不重构,就和考完试不把做错的题重新做一遍一样。

对于考试,如果考试完了不把错的题做一遍,不懂的还是不懂,你下次考还是会错。

对于代码的框架设计,如果写完代码不重构,就不会对现有的框架有改进。下次设计框架,要么设计一个没有进步的东西,要么设计一个没有验证过只是觉得会有改进的东西。

《禅与摩托车维修艺术》一书中说:

每一部摩托车都有属于它自己的声音和节奏,都有它自己的个性,培养车子的个性正是维修保养的真正目的。

你的程序也像一辆摩托车,它也有自己的个性,它正是靠持续重构培养出来的。

重构的真实驱动力来源于money,如果软件在商业上还有生命力,如果重构以后能提高后续软件维护开发的投入产出比。

现在讨论为什么重构以后可以提高软件的投入产出比?

假设针对软件已经实现的功能,以及有把握将要扩展的功能,存在一个最优设计(什么叫最优设计?先不讨论),那么若不刻意重构,软件打诞生那一刻起就一定不是最优设计,而且正在渐行渐远。重构就是把软件向这个最优设计回归的过程。

原因有三:

1,工程师的认识在不断深化,系统开发完了才真正了解系统。还有不少工程师,开发完几个系统才成长为工程师:-)。很多有洁癖的工程师都恨不得在系统杀青的那一刻推倒重来。

2,设计所依赖的前提在发生变化。通信行业是典型,系统诞生之处连操作系统,程序设计语言还有芯片都要自己开发(回忆一下bell labs都干了啥?),20年后这些东西都有了价廉物美的选项。

3,漫长生命周期中不断增加的新需求,这些需求不可能在系统设计之初都预测到,都预测到了也不可能都提前考虑好(这是要成本的),原来的设计可能不是很匹配这些新需求。拗一拗,总算是让新老需求共处一室了,拗的过程中难免产生累赘的适配层。

至于改bug,走捷径这些都不讲了。

最后,重不重构,一切唯钱是瞻。今天的不少行业,重构和重写都没必要,直接扔了,找个现成的软件配置配置就够了。更有甚者,抛弃软件,直接把相关业务委托给第三方。

其实最核心的一点是“现在的逻辑不能有效快速的支撑未来的逻辑”,我们要在何时的阶段去小步迭代去补这个“技术负债”。

在系统开发之初,系统用例比较少,软件的领域模型相对比较简单,但是随着系统用例的不断增多,发现领域模型不能有效的支撑,随即开发人员用错误的系统模型不断的增加各种判定路由、标记存储等去解决需求问题,最终导致软件逻辑里存在各种奇怪的特殊逻辑。这个过程有开发人员对软件理解不到位快速支撑需求的原因,也有本身为了方便并不想理解所有逻辑只是为了满足当前需求的逻辑等因素,导致软件逻辑越来越多复杂,以后修改一个点,可能需要对真个系统进行测试回归,甚至需要回归上下游依赖的系统,这也就增大了业务创新的成本了,这就是本质上的“技术负债”,也是我们软件开发过程中重构的技术驱动力。

责任编辑:
热门阅读排行
© 16货源网 1064879863