10

通过 Martin FowlerSteve McConnell的技术债务

YAGNI(你不需要它)通过维基百科

BDUF(前面的大设计)通过维基百科

更新:为了澄清这个问题,我想我也可以这样陈述并保持我的意思:

“作为一名敏捷实践者,您如何在每次迭代中在“快速和肮脏”(在尝试遵守 YAGNI 时无意冒着技术债务风险)和过度工程(BDUF)之间找到适当的平衡?

4

10 回答 10

4

似乎如果你坚持敏捷的“计划、执行、适应;计划、执行、适应”的敏捷理念(迭代、迭代审查),你会默认避免这些事情。BDUF 与敏捷估计和计划的理念完全相反,如果你真的很敏捷,你就不会自动成为 BDUF。

发布和迭代计划会议的目的是确保您为该迭代的项目添加最有价值的功能。如果您牢记这一点,您将免费避免使用 YAGNI。

我强烈推荐 Mike Cohn 关于敏捷规划的书籍:

  1. 应用用户故事
  2. 敏捷估计和计划

更新: 在您澄清在迭代中避免 YAGNI 和 BDUF 之后......

BDUF ...如果我觉得在开始工作之前没有明确定义某个功能,我会创建一个小的“功能”或故事来说明所需工作的设计类型部分。因此,可能较小的故事的故事点估计值为 1,而不是真实功能的 5。这样,设计将时间框化到较小的故事中,您将被驱使继续研究功能本身。

为了避免违反 YAGNI,我会非常清楚客户对迭代中某个功能的期望。只做符合客户期望的工作。如果您认为应该添加一些额外的东西,请为其创建一个新功能,并将其添加到待完成的工作积压中。然后,您会说服客户看到它的好处;就像客户会推动某个功能在某个时间点完成一样。

于 2008-09-16T16:42:33.700 回答
2

您似乎说“YAGNI”意味着“又快又脏”。我没有看到。

作为一名敏捷程序员,我练习测试驱动开发、代码审查和持续集成。

  • 测试驱动开发 (TDD) 作为一个过程,是避免 YAGNI 的好方法。“以防万一有用”的代码往往未经测试且难以测试。
  • TDD 还很大程度上消除了对 BDUF 的强迫:当您的流程是从坐下来开始做一些真正带来价值的事情时,您不能沉迷于 BDUF。
  • TDD,作为一种设计实践,意味着随着您获得解决问题的经验并重构真实代码,大型设计将出现。
  • 持续集成意味着您设计您的流程,以便您的产品基本上可以随时发布。这意味着您有一个集成的质量流程,试图防止主线的质量下降。

根据我的经验,技术债务的主要形式是:

  • 自动化测试套件未涵盖的代码。不要让这种情况发生,除非非常本地化的组件特别难以测试。未经测试的代码是损坏的代码。
  • 违反编码标准的丑陋代码。不要让这种情况发生。这就是您需要将代码审查构建到持续集成过程中的原因之一。
  • 有异味且需要重构以便更容易修改或理解的代码和测试。这是技术债务的良性形式。用你的经验知道什么时候积累,什么时候回报。

不确定这是否回答了你的问题,但我写得很开心。

Troy DeMonbreun 评论道:

不,那不是我的意思……“又快又脏”=(在尝试遵守 YAGNI 时无意冒着技术债务的风险”)。这并不意味着 YAGNI 只是又快又脏。短语“又快又脏”是我曾经在 Martin Fowler 对技术债务的描述中引用过的话

避免YAGNI是KISS的另一种说法。YAGNI 增加了技术债务。避免 YAGNI 和保持低技术债务之间没有矛盾。

我想我可能仍然错过了你的问题的重点。

于 2008-09-16T19:31:12.983 回答
2

几周前,基于您在 HanselMinutes 上完成的定义,有一个关于技术债务的有趣讨论 -完成了什么。该节目的基本内容是,如果您重新定义“完成”以提高感知速度,那么您将积累技术债务。这样做的必然结果是,如果您没有对“完成”的正确定义,那么您很可能会获得一份需要在发布前完成的项目列表,而不管设计方法如何。

于 2008-09-14T17:02:11.377 回答
1

只做最简单的事情。我同意 Ayende 的观点,他说敏捷的关键是“经常发布”。像这样的定期发布周期将意味着没有时间进行 BDUF,它还将阻止开发人员违反 YAGNI。

于 2008-12-22T23:50:04.473 回答
1

我发现 Robert Martin 的测试驱动开发 (TDD) 方法有助于解决这些问题。

为什么?

  • 您只需编写足够的代码即可通过下一个测试。
  • 我认为可测试的代码更干净。
  • 设计必须纳入测试,这有助于保持设计的重点。
  • 当您确实必须更改(重构)时,您需要依靠测试

无论何时编写测试(之前或之后),我发现编写测试可以帮助您做出实际决定。例如,我们选择了设计 A 或 B,因为 A 更易于测试。

于 2008-09-13T21:49:56.230 回答
1

“传统”的 XP 答案是重构与自动化单元测试相结合。

但从哲学上讲,这是一个非常有趣的问题。我认为您不需要避免技术债务,只需将其保持在可管理的水平即可。Steve McConnell 的文章很好地平衡了这种平衡——类比有效的原因是,只要你接受成本和风险,在公司中建立财务债务是正常且可以接受的——技术债务也可以。

或许答案本身也在于 YAGNI 的原理。在你这样做之前,你不需要偿还技术债务,那就是你进行重构的时候。当您在技术债务的系统领域进行大量工作时,请查看重新设计将产生多少短期差异。如果它足以让它变得有价值,那就还清吧。麦康奈尔关于维护债务清单的建议将帮助您了解何时进行此考虑。

我不认为有一个绝对的答案 - 就像很多事情一样,它是基于你的经验、直觉和你在每种特定情况下的分析的判断。

于 2008-09-13T22:01:15.220 回答
1

在我工作的地方,我相信我们避免债务的方法是快速完成整个周期,即向最终用户展示功能,然后得到一个应该推动测试的签名,或者拒绝说出什么是错的给出更新的要求。通过在迭代中重复执行此操作,可以通过尝试这个和那个来找到关于用户想要什么的很多变化。

一个关键点是尝试完全按照用户的意愿去做,因为做的更多违反了 YAGNI 并引入了 BDUF,而一遍又一遍地提炼需求的想法是我认为敏捷的核心。

于 2009-10-01T21:08:45.550 回答
0

这就是为什么写好的“学术论文”总是更容易,谈论敏捷开发有多好,什么是“最佳实践”等等。

这就是为什么你会发现很多“合适的工程师”组成了新的软件工程技术。

过程很重要,保持最佳实践很酷,但最重要的是,常识驱动设计过程。软件是由人开发的,所以 YAGNI 真的应该是:

我可能不需要,但也许我会,因为在我的具体业务/公司/部门中,这件事确实会发生,或者我会需要它,但我只是没有时间,没有那么快速和肮脏的黑客来赚钱并保住我的工作,或者我可能需要它,以后重构将比现在从头开始做的成本高出 10 倍,而且我现在有时间。

所以使用你的常识,相信它或相信为你工作的人的常识。不要把每一篇学术论文都当作事实证明,经验是最好的老师,你的公司应该随着时间和自己的经验改进他们的方式或做事。

编辑:顺便说一句,TDD 与 YAGNI 是相反的,你甚至在知道你是否需要它们之前就已经构建了测试。说真的,别再听学术了!!制作软件没有神奇的方法。

于 2008-09-13T21:50:19.897 回答
0

对于任何给定的项目,敏捷肯定会降低您的 TD 吗?

事实上,您正在实施客户想要的,即通过他们的反馈,将 TD 保持在最低限度,

于 2008-09-13T22:30:43.293 回答
0

问题实际上可能在更高的层面:管理层和产品负责人关心截止日期,而不是开发人员自己。

在我最后一个工作的地方,我从事遗留代码工作,但与使用(据说)敏捷和 TDD 开发全新代码的人保持联系。

现在 TDD 应该是红 - 绿 - 重构:编写失败的测试,做最少的事情以通过测试,然后重新编写代码以使其更易于维护,同时确保它仍然通过测试。

但是……进度是通过用户故事的实施速度来衡量的,即添加新功能的速度。重构的关键在于它不会添加任何新功能。是的,它非常重要,但它并没有像向产品所有者展示新功能甚至测试代码行那样立即产生影响。

随着截止日期越来越近,加班成为标准,人们有动力在重构部分吝啬。这样做的越多,通过用户故事的速度就越快,这似乎是管理层所关心的。

现在,这确实导致了技术债务,因为在许多情况下,为了完成下一个用户故事,事实证明有必要返回并重构 - 真正重写 - 前一堆用户故事的代码。管理层对此感到愤怒,因为从他们的角度来看,所讨论的用户故事看起来与以前的用户故事并没有太大的不同,那么为什么对它的估计要长 10 倍呢?

(事情也有一个丑陋的博弈论方面。如果你或你的团队对重构认真,这并没有阻止你在另一个团队之后被困在清理。当然,另一个团队看起来更好,因为他们在相同的时间内完成了更多的用户故事。)

我的观点是,如果做得好,TDD 可能不会导致技术债务。但要正确完成,必须有来自高层的真正支持。

于 2017-08-08T22:39:34.943 回答