什么时候可以不修复损坏的窗户?


21

关于残破的窗口,是否有时最好将重构留给以后的活动?

例如,如果将一个向现有内部系统添加一些新功能的项目分配给了一个到目前为止尚未与该系统合作的团队,并且给出了一个可与之合作的时间表,那么是否有理由这样做?为了在这种情况下规定截止日期,将主要的重构推迟到现有代码吗?


6
有时,老板决定不修理破损的窗户,因为他知道以后再修理整个房子会赚很多钱。
mouviciel 2012年

1
基本规则:技术债务可以在截止日期前完成,但最终必须予以赔偿,而且越早越好
JF Dion 2012年

4
恭喜你!您完美地描述了PHP的“设计理念”。
ThomasX 2012年


4
明天永远不会来...
埃里克·金

Answers:


25

重构是(并且应该是)一个持续的过程。仅通过工作和经过测试的实现(仍然有些不完整)来简单地满足需求是不够的。

“使它工作,然后使其更好地工作”

我不记得在哪里读过那句话,但这是正确应用重构的关键,我认为这样做不专业。

连续重构就像在烹饪时擦去溢出物,在吃完饭后清洗碗碟。有针对性的重构就像找到一个肮脏的厨房,但是只有时间来清洗一两个脏玻璃。您是希望住在一个连续肮脏的厨房里,还是在旅途中保持物品整洁?

您使代码正常工作,然后重构代码以确保您拥有可以使用的最佳实现。如果您正在做一些熟悉的事情,可能是您第一次实现了最佳代码,但是需要花一点时间仔细检查您的工作以确保。如果看起来您可以改进代码,则尝试进行重构以确保您的代码至少精简而干净。这意味着您将减少留下的技术债务,并使您在下次处理代码时更容易阅读和重构。这是TDD口头禅“ Red-Green-Refactor”的核心价值,除了在TDD中您主要进行重构以消除重复的地方外,还需要检查其他可以重构的项,例如大型类,长方法,

如果您发现自己要进行重大的重新设计,则可以推迟一会儿,尤其是在计划中按时运行时间很短的情况下。但是,前提是您的代码功能不会受到损害,并且前提是实现将继续满足要求。这种情况应该很少发生,并且如果您在进行过程中不断进行重构,则可以帮助确保这种情况更加罕见。但是,更重要的是您不能冒险将重大更改留得太久,否则您将在以后创建更大的工作负载,这可能会导致修复成本高得多,或者最终导致成本更高。项目失败。

我给人的印象是,许多人倾向于混淆重构重新设计的定义。这两个术语描述了管理非常不同情况的策略。如果您希望进行重新设计,那就意味着要做出重大改变,这将改变系统的行为。这将使某些测试无效,并且还需要新的测试。当你重构,您可以确保你的系统继续表现究竟与更改之前相同,但是您还要确保代码的寿命长,并且随着时间的推移更易于维护。您并没有为自己的代码“拉皮条”,而是致力于采用干净的代码的专业标准,这将减少失败的风险,并确保您的代码保持愉快的工作和专业的标准。

回到破损的窗户类比,如果您打碎窗户,则应立即修复。如果您没有注意到窗户被打碎,那么您需要决定是否让窗户打碎而要付出的代价。现在,重复前面的两个句子,但是用Bug代替window。您最终需要不同的策略。如果您在编写代码时创建了错误,则可以立即对其进行修复,或者查看是否需要重新设计更改,并就何时最佳解决问题做出商业决策。因此,您无需进行重构来解决问题,而是进行重构以确保更容易发现和解决问题。我不在乎您认为您的代码有多神奇,复杂的系统将始终存在需要逐步解决的问题。这就是技术债务的全部内容,以及为什么在实现代码时重构需要是一个持续的过程,而不是让它留给将来任意的时间。

简而言之,答案是在极少数情况下可以推迟对代码的重大更改以形成截止日期,但这是不可接受的,但是不应将重构视为独立于日常实现工作的练习,这是正常做法。从来没有被不熟悉代码库的团队作为借口,以避免确保他们的实现尽可能精简和干净。


喜欢报价。
Marjan Venema 2012年

1
在很多地方,“稀有时间”是常态。
ozz 2012年

2
如果只有PHP的“设计者”认可了这个报价……
ThomasX 2012年

1
很好的报价,考虑一下-您是否想让您的汽车油漆工采用相同的逻辑来修理1999年的Toyota-如果是,您是否愿意为$ 1000的汽车上的Roll Royce油漆付款?
mattnz

@mattnz您的类比在软件开发中并不成立。这不是“镀金”的情况,它是一种相对较低的首付,以确保您获得最大的投资回报。窃取您的绘画类比,这之间的区别还在于用宽大的刷子在汽车上打上一层油漆,或者使用喷漆室获得均匀的光洁度。您得到了所要支付的费用,那么您是否要支付专业人士的费用并获得一份半成品?偷工减料在短期内可能会节省一点,但从长期来看会招致更多的技术债务。
S.Robins'4

11

一些开发人员说,他们实际上是在“重新布置泰坦尼克号上的躺椅”时,他们正在“修复窗户破损”。重构有效但会冒犯您的嗅觉的代码相对容易。如果您发现自己继续执行此类任务,而不是为用户添加新功能,或者使应用程序对用户更有用(优化意味着使应用程序运行得更快,那么优化意味着使代码更具可读性是很不错的选择)。不同),那么也许您整理得太多了。并不是因为收拾工作不好,而是因为公司为开发某些东西而付出了发展的代价。可以肯定的是,他们不需要脆弱的,难以理解的,架构不佳的解决方案,但是,他们也不需要精致而优美的半解决方案。

当您需要做一些简单的“事情”时,或者在等待另一个团队告诉您您的问题实际上是他们的错时,还是在等待决策时,请整理一下。会有很多机会。如果您有机会将整个应用程序向前移动,请采用它,除非您开始觉得整个应用程序变得很脆弱。可能还没有。您将有机会进行重构-您无需为此担心。

回到您的问题的下半部分,一个短时间添加功能的冲刺,说“我们不会进行任何重构,没有时间”是错误的。说“我知道已经过去了6周,并且对用户来说看起来完全一样,但是这些破损的窗户确实需要修复”,这也是错误的。使重构适合任何项目中发生的空白。不要为了收拾项目目标而收拾一切。


4
一些开发人员说,他们实际上是在“重新布置泰坦尼克号上的躺椅”时,他们正在“修复破损的窗户” -实际上,开发人员通常很难分辨“技术债务”与“不是我想的那样”之间的区别。已经做到了”
RevBingo 2012年

9

从业务角度来看,重构是一种投机性投资-现在投资时间和精力(金钱),以期在将来的某个时候可以节省更多的时间和精力(金钱)。

无需争论重构方面的工作将节省多少费用(这取决于太多变量,在这里不能进行充分的讨论),显然重构的时间就是“净现值”留下的成本超过了现在的成本。

那很容易,除非您不知道该家具要花多少钱。您还需要考虑所有正常的财务计划构想,例如投资回报率,风险管理(品牌价值,法律责任,可保与不可保风险),运营成本等。

在大多数情况下,决定何时进行重构最好由经营企业的人员来决定。尽管论坛上有很多标语,但经理通常比程序员更了解经营业务。他们有一个更大的构想,包括使股东的回报最大化。修复未损坏的东西很少会造成这种情况,代码也不例外。

编辑:我读了一篇有趣的文章,关于关键基础架构的维护计划。要点是,该机芯远离日常维护(重构),可以在需要时进行修复(修复错误)。主要区别在于监视级别-例如,核电厂进行的详细监视非常严格,并在“损坏”时修复,但在故障发生之前就修复。已经发现的是,固定到维修计划表不仅花费更多,而且由于维修程序引起的停机而可靠性降低。软件也需要类似的想法-重构即将中断的位-您只能通过测量才能知道。


4
+1尽管有拼写错误:); 大多数情况下,客户不为干净的代码付费-他们为结果付费。如果您拥有干净的代码,但没有结果,那么您将无法获得报酬,也不会长期重构。
jasonk'4

2
我只想指出,经理对整个业务有更好的了解是很普遍的。不幸的是,他们通常对将来的错误代码会产生怎样的后果感到担忧,因此,如果您要信任经理做出此决定,请确保您的经理有一些合理的成本数据可以使用。
迈克尔·科恩

观察重构的另一种方式不是作为目标任务来决定要做的事情,而是一种确保在开发系统时不会绊倒自己的方法。通常,您会发现分解不佳的代码会导致您不断修改测试,并在进行过程中尝试扑灭现场。结果,这可能使您的客户花费更多的时间。保持代码干净不应被视为是您的代码镀金,而是被视为保持专业标准以便交付成功的结果。
S.Robins 2012年

1
@ S.Robins我们在谈论的是重构,而不是分解不好的代码(在我看来,第二个是问题,第一个很不错)。
jasonk'4

5

通过修复而不是不修复对企业造成的损失要大时,这是可以接受的。

发生这种情况的情况可能是:

  • 由于需要时间修复而错过了最后期限或商业机会
  • 一段代码(通常)计划在很短的时间内退出,因此重构它几乎没有好处。

而且确实发生了这些情况-商业情况通常会在人为的截止日期之前达成,必须要在经过谈判的机会已经过去的情况下才能满足,并且有时间成分的要求也必须这样做-例如,法律的变更或税收规则的生效一个特定的日期-确实存在。

诀窍是识别这些情况并正确评估它们。计划退休的代码通常会保留数年。可能需要满足人为的截止日期,但是通常可以通过不同的方式来满足(例如,可以在给定的日期上展示,演示和“发布”软件,而不必最终发行版本要等到以后)。

当遇到这种事情时,您需要以开放的心态来对待它,但总是问它看起来是什么?涉及的假设是否现实?如果不交付不合标准的代码,还有另一种达到目标的方法吗?如果没有,我如何最好地利用我的空闲时间?

如果没有其他选择总是可以的,那么我们何时才能解决呢?

因为它应该几乎,几乎,几乎总是在when而不是if


回复:人为的截止日期;在理想的世界中,任何体面的项目都应有最后期限。我听说产品团队可以每周减少一个星期(没什么大不了吗?)-却没有意识到商业动机-这使您在黑色星期六之后,而之前。不好的举动。
jasonk'4

3

如果管理者决定他们要积累技术债务。这是一个公平的决定,例如,如果一个人只想向一些初始客户提供早期原型,以获得早期反馈。


4
这种情况发生得太频繁了,在这种情况下,经理们允许增加技术债务以应付紧迫的最后期限,而不是尽快偿还债务,他们看到下一个最后期限迫在眉睫,而不是及时安排即将到来的工作先前的债务,债务将被忽略,所需时间充满了其他新功能以供发布。换句话说,债务永远都不会还清,在您还没意识到项目有多深的麻烦之前,为避免问题失控而采取任何行动为时已晚。只要您能迅速还清债务,就可以累积债务。
S.Robins 2012年

2
当提到技术债务时,有些经理(尤其是非技术人员)不知道您在说什么。有些人甚至认为您正在试图让他们只是走开玩弄而不是从事实际工作。
quick_now 2012年

这就是为什么我们的组织没有经理的原因:Open-Org.com;)
David

1
大多数管理人员不够聪明,无法理解技术债务的弊端,因此最终导致的是不断累积的技术债务,直到技术破产并被迫重写整个系统为止。
韦恩·莫利纳

1

您可以像索取信用一样思考它。可以借钱短期投资X并长期支付吗?没有明确的答案,这可能符合组织的最大利益(例如,满足当前客户的期望),或者如果不负责任地这样做可能是一场灾难。

一切都取决于优先级,并且管理层应该意识到,尽管第一优先级是使“代码工作”,实现新功能以及满足客户期望,但每次您离开破碎的窗口时,都会使第一优先级变慢,难度更大,并且需要更多的资源投入。同样,有99%的时间停止开发新功能并将所有精力都集中在“修复代码库”上是不可行的。

总而言之,是的,有时候留下破烂的窗户是可以接受的,就像可以申请贷款一样……只是记住,您将来确实需要为之付款。而且在将来,执行此操作的时间很可能不会比您现在拥有的时间长很多。


0

通常,只要有能力,就应该对其进行修复,这样可以避免潜在的维护时间。但是,一些野蛮的非敏捷实践倾向于让现状保持现状,只要它一直在起作用。一些管理人员担心这种变化的“不可预见的影响”。

我的看法是,仅当它按预期方式运行时才保留它(只能通过优化而不是功能来破坏),并且如果进行一些重构,则您没有时间测试它。但是,您应该注意,应尽快将其修复。

如果它被功能破坏了,而您又依赖于它的新功能,那么最好也尽快修复它。


0

大多数程序员都在为雇主赚钱。因此,何时应该进行重构:何时能赚到您的公司钱。重构是指不花在其他项目上的时间以及将来在该项目上节省的时间。

是否值得主要取决于您的经理。


1
-1; 这种态度是导致软件系统崩溃的原因,因为重构被视为“可以花在新事物上的时间”。
韦恩·莫利纳

1
重构IS时间不花在新事物上。
Pieter B

@Wayne M:事情是软件工程师通常无法决定要完成什么事情,而业务和经理则可以。当然,每个人都想在任何需要的地方进行重构,但这确实不是现实……至少在我7年的专业经验中。
詹姆斯

+1这种态度可以为付薪的人带来价值。没有它,您的整个工作可能会外包。
MarkJ

0

程序员应让业务方知道技术债务的范围,以便他们可以做出明智的决定。如果需要尽快进入市场的风险超过了编写代码的风险,则您别无选择。现金流不足将胜过许多技术决策。

为了从非技术角度考虑一些问题,请指出延长的时间来修复错误和添加新功能。如果管理层具有销售和营销背景,他们可能会理解。他们讨厌必须告诉客户这些事情将花费更长的时间。

如果您正在考虑扩大团队规模,那么这可能是雇用初级开发人员的好时机。在这种情况下,测试覆盖率将是一个巨大的救星。他们将从中学到更多的知识,而不是阅读文档。


0

为了在这种情况下确定截止日期,将主要重构推迟到现有代码是否合理?

  • 如果有东西坏了,那么很可能不会。您不会驾驶带有部分起作用的制动器的汽车,对吗?(除非不按时到达某处的风险大于因刹车故障而导致撞车的风险。)并非理想的解决方案,但不幸的是,这种解决方案会发生。

但是,如果您正在谈论重构工作代码,那么我将考虑以下内容:

  • 如果由我们的高级开发人员或技术总监来决定,那么我们将永远不会发布任何软件。我们将始终重构并追求完美主义。

  • 如果重构将对业务的盈利能力产生负面影响,则应重新计划。

  • 如果您的企业承诺在给定日期之前交付某些功能,那么您将在以后进行重构。想想红鼻子日的慈善活动-每年他们可以在24或48小时内收集捐款。如果他们认为这样做可能会阻止他们在这段时间里接受捐赠,他们将无法重构其代码库。此外,如果窗户破了,但不会影响他们的捐款能力,那么他们很可能会选择不重构。

  • 您将永远找到做某事的更好方法。这是一个自然的过程,能够划清界限非常重要。


希望获得有关否决票的反馈:D
CodeART 2012年

2
同意,有很多减票,看来某人过得很糟糕,并在一堆不赞成票的情况下遭受重创。
山姆·戈德堡

-1

在回答您有关重构的问题时,我会说“是”。就像其他人在上述答案中指出的那样,重构是一个持续的过程,有时,战术和业务决策取代了重写已经在起作用的代码的需要(尽管可能是笨拙的)。

关于“破窗”:大约10年前,我在软件开发的背景下第一次听到了这个术语。但是在那时,它用来描述允许损坏的单元测试。这是在描述人们倾向于不修复损坏的单元测试的情况,因为似乎更方便的是只记住哪些测试“可以失败”,而不是修复损坏的测试(由于接口或要求而被有效破坏的测试)更改)。

我认为将残破的窗口隐喻应用于残破的单元测试更合适,并且更能说明在软件邻域中允许“残破的窗口”的危险。在我看来,如果您正在谈论损坏的单元测试(如损坏的窗口),那么答案将是永远不行。(就我们可以说永远不会...)


否决票的原因是什么?这里说的话不正确吗?还是只是斗气的编辑?
山姆·戈德堡

-1

如果它真的坏了,那就应该修复。

但这真的坏了吗?您确定您不只是将破损等同于“不漂亮”。

在重构工作代码之前,您需要应用“下沉值”计算,因为您不喜欢该样式,或者因为您认为它将来会引起问题。

对于上周编写的代码重构,沉没成本是上周花费在编写代码上的时间,如果代码得到了实质性的改进,这并不值得费心。

重构已经通过单元测试的代码。现在,您不仅需要重新编写,还需要重新定义并重新运行到目前为止完成的所有测试,这看起来似乎很昂贵。

重构已投入生产的代码。还要做更多的测试,以及向用户推广,以及交付不如旧版本的产品的风险。您需要证明这一点并与大老板清除,然后再继续。

重新整理已在生产中使用了一段时间的代码,并已通过多个发行版和错误修复进行了编码。除非您知道该软件将停止运行,否则请不要去那里!


通常,“不漂亮”与“残缺”并驾齐驱。编写不正确的代码更难维护和添加新功能,因此最终您将不得不重写该代码,因为您忽略了重构的过程。
韦恩·莫利纳

2
经过测试且在生产中且没有未完成的错误报告的代码正在工作。人们花费了大量时间和金钱来使它进入该状态。漂亮的代码就是这样-漂亮的代码。
詹姆斯·安德森

我不同意。代码可以工作,但是维护和添加功能很麻烦;这样的代码被破坏了,因为它死板而“臭”。正确编写的代码通常很漂亮且经过测试,更重要的是易于维护和增强。
韦恩·莫利纳

@韦恩男:哇,韦恩,你真的不知道。如果您成功进入PM,您的开发人员就会爱上您,但是您的职业生涯可能不会很长。您必须在某些时候画线。我认为是您对所有不同意您梦想的人的不满?
詹姆斯

1
@WayneM -因为您不喜欢代码的外观,所以会引发“缺陷”。编写代码是为了完成一项工作-如果执行该工作,那么它将正常工作。维护成本可能很高,但它必须比重写便宜。
詹姆斯·安德森

-2

根据我的经验,截止日期对于企业来说是最重要的。这实际上取决于谁将使用您的应用程序。就我而言,这是针对手机操作系统软件的……错过了最后期限意味着错过了销售目标和股价。

在查看我们继承并显然需要更改的代码时,我们遇到了很多WTF时刻。但是,由于该代码“正好”起作用(异步性被人们很少理解),因此在执行未完成的承诺的同时,也没有激励管理层真正允许进行重构。直到看到一个“野外”的错误,才允许我们进行任何更改,即使我们可以通过晦涩的边缘案例轻松地将其自行破解。我曾经在自己的时间里重构过大约1万行代码,最终不得不将其丢弃。测试和其他审核所需的时间无法证明。


我很高兴软件发展的现实似乎失去了一些人
詹姆斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.