关于残破的窗口,是否有时最好将重构留给以后的活动?
例如,如果将一个向现有内部系统添加一些新功能的项目分配给了一个到目前为止尚未与该系统合作的团队,并且给出了一个可与之合作的时间表,那么是否有理由这样做?为了在这种情况下规定截止日期,将主要的重构推迟到现有代码吗?
关于残破的窗口,是否有时最好将重构留给以后的活动?
例如,如果将一个向现有内部系统添加一些新功能的项目分配给了一个到目前为止尚未与该系统合作的团队,并且给出了一个可与之合作的时间表,那么是否有理由这样做?为了在这种情况下规定截止日期,将主要的重构推迟到现有代码吗?
Answers:
重构是(并且应该是)一个持续的过程。仅通过工作和经过测试的实现(仍然有些不完整)来简单地满足需求是不够的。
“使它工作,然后使其更好地工作”。
我不记得在哪里读过那句话,但这是正确应用重构的关键,我认为这样做不专业。
连续重构就像在烹饪时擦去溢出物,在吃完饭后清洗碗碟。有针对性的重构就像找到一个肮脏的厨房,但是只有时间来清洗一两个脏玻璃。您是希望住在一个连续肮脏的厨房里,还是在旅途中保持物品整洁?
您使代码正常工作,然后重构代码以确保您拥有可以使用的最佳实现。如果您正在做一些熟悉的事情,可能是您第一次实现了最佳代码,但是需要花一点时间仔细检查您的工作以确保。如果看起来您可以改进代码,则尝试进行重构以确保您的代码至少精简而干净。这意味着您将减少留下的技术债务,并使您在下次处理代码时更容易阅读和重构。这是TDD口头禅“ Red-Green-Refactor”的核心价值,除了在TDD中您主要进行重构以消除重复的地方外,还需要检查其他可以重构的项,例如大型类,长方法,
如果您发现自己要进行重大的重新设计,则可以推迟一会儿,尤其是在计划中按时运行时间很短的情况下。但是,前提是您的代码功能不会受到损害,并且前提是实现将继续满足要求。这种情况应该很少发生,并且如果您在进行过程中不断进行重构,则可以帮助确保这种情况更加罕见。但是,更重要的是您不能冒险将重大更改留得太久,否则您将在以后创建更大的工作负载,这可能会导致修复成本高得多,或者最终导致成本更高。项目失败。
我给人的印象是,许多人倾向于混淆重构和重新设计的定义。这两个术语描述了管理非常不同情况的策略。如果您希望进行重新设计,那就意味着要做出重大改变,这将改变系统的行为。这将使某些测试无效,并且还需要新的测试。当你重构,您可以确保你的系统继续表现究竟与更改之前相同,但是您还要确保代码的寿命长,并且随着时间的推移更易于维护。您并没有为自己的代码“拉皮条”,而是致力于采用干净的代码的专业标准,这将减少失败的风险,并确保您的代码保持愉快的工作和专业的标准。
回到破损的窗户类比,如果您打碎窗户,则应立即修复。如果您没有注意到窗户被打碎,那么您需要决定是否让窗户打碎而要付出的代价。现在,重复前面的两个句子,但是用Bug代替window。您最终需要不同的策略。如果您在编写代码时创建了错误,则可以立即对其进行修复,或者查看是否需要重新设计更改,并就何时最佳解决问题做出商业决策。因此,您无需进行重构来解决问题,而是进行重构以确保更容易发现和解决问题。我不在乎您认为您的代码有多神奇,复杂的系统将始终存在需要逐步解决的问题。这就是技术债务的全部内容,以及为什么在实现代码时重构需要是一个持续的过程,而不是让它留给将来任意的时间。
简而言之,答案是在极少数情况下可以推迟对代码的重大更改以形成截止日期,但这是不可接受的,但是不应将重构视为独立于日常实现工作的练习,这是正常做法。从来没有被不熟悉代码库的团队作为借口,以避免确保他们的实现尽可能精简和干净。
一些开发人员说,他们实际上是在“重新布置泰坦尼克号上的躺椅”时,他们正在“修复窗户破损”。重构有效但会冒犯您的嗅觉的代码相对容易。如果您发现自己继续执行此类任务,而不是为用户添加新功能,或者使应用程序对用户更有用(优化意味着使应用程序运行得更快,那么优化意味着使代码更具可读性是很不错的选择)。不同),那么也许您整理得太多了。并不是因为收拾工作不好,而是因为公司为开发某些东西而付出了发展的代价。可以肯定的是,他们不需要脆弱的,难以理解的,架构不佳的解决方案,但是,他们也不需要精致而优美的半解决方案。
当您需要做一些简单的“事情”时,或者在等待另一个团队告诉您您的问题实际上是他们的错时,还是在等待决策时,请整理一下。会有很多机会。如果您有机会将整个应用程序向前移动,请采用它,除非您开始觉得整个应用程序变得很脆弱。可能还没有。您将有机会进行重构-您无需为此担心。
回到您的问题的下半部分,一个短时间添加功能的冲刺,说“我们不会进行任何重构,没有时间”是错误的。说“我知道已经过去了6周,并且对用户来说看起来完全一样,但是这些破损的窗户确实需要修复”,这也是错误的。使重构适合任何项目中发生的空白。不要为了收拾项目目标而收拾一切。
从业务角度来看,重构是一种投机性投资-现在投资时间和精力(金钱),以期在将来的某个时候可以节省更多的时间和精力(金钱)。
无需争论重构方面的工作将节省多少费用(这取决于太多变量,在这里不能进行充分的讨论),显然重构的时间就是“净现值”留下的成本超过了现在的成本。
那很容易,除非您不知道该家具要花多少钱。您还需要考虑所有正常的财务计划构想,例如投资回报率,风险管理(品牌价值,法律责任,可保与不可保风险),运营成本等。
在大多数情况下,决定何时进行重构最好由经营企业的人员来决定。尽管论坛上有很多标语,但经理通常比程序员更了解经营业务。他们有一个更大的构想,包括使股东的回报最大化。修复未损坏的东西很少会造成这种情况,代码也不例外。
编辑:我读了一篇有趣的文章,关于关键基础架构的维护计划。要点是,该机芯远离日常维护(重构),可以在需要时进行修复(修复错误)。主要区别在于监视级别-例如,核电厂进行的详细监视非常严格,并在“损坏”时修复,但在故障发生之前就修复。已经发现的是,固定到维修计划表不仅花费更多,而且由于维修程序引起的停机而可靠性降低。软件也需要类似的想法-重构即将中断的位-您只能通过测量才能知道。
通过修复而不是不修复对企业造成的损失要大时,这是可以接受的。
发生这种情况的情况可能是:
而且确实发生了这些情况-商业情况通常会在人为的截止日期之前达成,必须要在经过谈判的机会已经过去的情况下才能满足,并且有时间成分的要求也必须这样做-例如,法律的变更或税收规则的生效一个特定的日期-确实存在。
诀窍是识别这些情况并正确评估它们。计划退休的代码通常会保留数年。可能需要满足人为的截止日期,但是通常可以通过不同的方式来满足(例如,可以在给定的日期上展示,演示和“发布”软件,而不必最终发行版本要等到以后)。
当遇到这种事情时,您需要以开放的心态来对待它,但总是问它看起来是什么?涉及的假设是否现实?如果不交付不合标准的代码,还有另一种达到目标的方法吗?如果没有,我如何最好地利用我的空闲时间?
如果没有其他选择总是可以的,那么我们何时才能解决呢?
因为它应该几乎,几乎,几乎总是在when而不是if。
如果管理者决定他们要积累技术债务。这是一个公平的决定,例如,如果一个人只想向一些初始客户提供早期原型,以获得早期反馈。
您可以像索取信用一样思考它。可以借钱短期投资X并长期支付吗?没有明确的答案,这可能符合组织的最大利益(例如,满足当前客户的期望),或者如果不负责任地这样做可能是一场灾难。
一切都取决于优先级,并且管理层应该意识到,尽管第一优先级是使“代码工作”,实现新功能以及满足客户期望,但每次您离开破碎的窗口时,都会使第一优先级变慢,难度更大,并且需要更多的资源投入。同样,有99%的时间停止开发新功能并将所有精力都集中在“修复代码库”上是不可行的。
总而言之,是的,有时候留下破烂的窗户是可以接受的,就像可以申请贷款一样……只是记住,您将来确实需要为之付款。而且在将来,执行此操作的时间很可能不会比您现在拥有的时间长很多。
通常,只要有能力,就应该对其进行修复,这样可以避免潜在的维护时间。但是,一些野蛮的非敏捷实践倾向于让现状保持现状,只要它一直在起作用。一些管理人员担心这种变化的“不可预见的影响”。
我的看法是,仅当它按预期方式运行时才保留它(只能通过优化而不是功能来破坏),并且如果进行一些重构,则您没有时间测试它。但是,您应该注意,应尽快将其修复。
如果它被功能破坏了,而您又依赖于它的新功能,那么最好也尽快修复它。
为了在这种情况下确定截止日期,将主要重构推迟到现有代码是否合理?
但是,如果您正在谈论重构工作代码,那么我将考虑以下内容:
如果由我们的高级开发人员或技术总监来决定,那么我们将永远不会发布任何软件。我们将始终重构并追求完美主义。
如果重构将对业务的盈利能力产生负面影响,则应重新计划。
如果您的企业承诺在给定日期之前交付某些功能,那么您将在以后进行重构。想想红鼻子日的慈善活动-每年他们可以在24或48小时内收集捐款。如果他们认为这样做可能会阻止他们在这段时间里接受捐赠,他们将无法重构其代码库。此外,如果窗户破了,但不会影响他们的捐款能力,那么他们很可能会选择不重构。
您将永远找到做某事的更好方法。这是一个自然的过程,能够划清界限非常重要。
在回答您有关重构的问题时,我会说“是”。就像其他人在上述答案中指出的那样,重构是一个持续的过程,有时,战术和业务决策取代了重写已经在起作用的代码的需要(尽管可能是笨拙的)。
关于“破窗”:大约10年前,我在软件开发的背景下第一次听到了这个术语。但是在那时,它用来描述允许损坏的单元测试。这是在描述人们倾向于不修复损坏的单元测试的情况,因为似乎更方便的是只记住哪些测试“可以失败”,而不是修复损坏的测试(由于接口或要求而被有效破坏的测试)更改)。
我认为将残破的窗口隐喻应用于残破的单元测试更合适,并且更能说明在软件邻域中允许“残破的窗口”的危险。在我看来,如果您正在谈论损坏的单元测试(如损坏的窗口),那么答案将是永远不行。(就我们可以说永远不会...)
如果它真的坏了,那就应该修复。
但这真的坏了吗?您确定您不只是将破损等同于“不漂亮”。
在重构工作代码之前,您需要应用“下沉值”计算,因为您不喜欢该样式,或者因为您认为它将来会引起问题。
对于上周编写的代码重构,沉没成本是上周花费在编写代码上的时间,如果代码得到了实质性的改进,这并不值得费心。
重构已经通过单元测试的代码。现在,您不仅需要重新编写,还需要重新定义并重新运行到目前为止完成的所有测试,这看起来似乎很昂贵。
重构已投入生产的代码。还要做更多的测试,以及向用户推广,以及交付不如旧版本的产品的风险。您需要证明这一点并与大老板清除,然后再继续。
重新整理已在生产中使用了一段时间的代码,并已通过多个发行版和错误修复进行了编码。除非您知道该软件将停止运行,否则请不要去那里!
根据我的经验,截止日期对于企业来说是最重要的。这实际上取决于谁将使用您的应用程序。就我而言,这是针对手机操作系统软件的……错过了最后期限意味着错过了销售目标和股价。
在查看我们继承并显然需要更改的代码时,我们遇到了很多WTF时刻。但是,由于该代码“正好”起作用(异步性被人们很少理解),因此在执行未完成的承诺的同时,也没有激励管理层真正允许进行重构。直到看到一个“野外”的错误,才允许我们进行任何更改,即使我们可以通过晦涩的边缘案例轻松地将其自行破解。我曾经在自己的时间里重构过大约1万行代码,最终不得不将其丢弃。测试和其他审核所需的时间无法证明。