为将来的更改而设计或解决眼前的问题[关闭]


37

在编写代码或进行设计时,您会尝试在一开始就将问题概括化,或者尝试解决非常具体的问题。

我之所以这样问,是因为试图概括问题会导致事情复杂化(可能没有必要),另一方面,如果需求发生变化,扩展特定解决方案将非常困难。

我猜解决方案是找到一条说起来容易做起来难的中间路径。您如何解决这类问题?如果您在什么时候开始对其进行泛化,您知道泛化足够了吗?



这提出了一个非常重要的问题:您能否真正预测需求的变化方式?
user16764 2013年

很多人会告诉你YAGNI。当您不得不接管他们的工作时,这些就是您所鄙视的人。
马丁·马特

Answers:


60

当您尝试为未来进行设计时,常常会发现您对未来需求的预测是错误的。通常,当您真正了解需求的变化时重构比第一天就过度设计系统要好。同时,也不要用脚射击自己。当然有中间立场,并且知道哪里比艺术更重要。

归结为一个经验法则:少即是多。


17
+1“未来不再是过去。”
丹·里昂斯2013年

19

您熟悉敏捷吗?YAGNI是敏捷的一大原则。我发现这是处理事情的最佳方法。

“您将不需要它” ……是极限编程(XP)的原则,该原则规定程序员在认为必要之前不应添加功能。罗恩·杰弗里斯Ron Jeffries)写道:“始终在真正需要它们时执行事情,而永远不会仅仅在预见到需要它们时就执行。”

... YAGNI是XP实践“做可能可行的最简单的事情”(DTSTTCPW)背后的原则。它旨在与其他几种实践结合使用,例如连续重构,连续自动化单元测试连续集成。在不进行连续重构的情况下使用它可能会导致代码混乱和大量返工。连续重构又依赖于自动化的单元测试作为安全网(以检测不可预见的错误)和连续集成以防止更广泛的集成问题。

即使结合支持实践,YAGNI也不被普遍接受为有效原则。XP最初定义的一部分就是需要将其与支持实践相结合,而不是单独使用。


3
尽管我或多或少地同意YAGNI,但我在敏捷原则中找不到它:agilemanifesto.org/principles.html
Jens Schauder,2009年

“简单-最大化未完成工作量的艺术-是必不可少的,”将适用于YAGNI和其他一些敏捷实践。
tvanfosson

1
尽管宣言中并未具体说明“ YAGNI”,但我认为它们彼此非常吻合。

2
@Jens和@Matt(YAGNI)通过将XP捆绑为“敏捷”方法而处于敏捷中。如Wikipedia文章所述,YAGNI原则是Ron Jeffries开发的,是XP核心实践的一部分。

1
YAGNI确实是开发人员的惯用语,但TDD是很好地解决了这一难题的人。在该步骤中,您应该只编写足以通过测试的代码,而无需再进行其他测试。TDD是敏捷的一部分。
罗伯特·科里特尼克'16

12

这可能是软件开发中最困难的部分之一,因为您需要在“ YAGNI”和“ PYIAC”(将自己绘制到一个角落)之间走一条路线。

很容易说“除非需要就不要编写功能”。困难的部分是设计代码,以便以后在需要时可以轻松添加功能。

关键是要能够设计一种可扩展的体系结构,使您编写的代码不会超出当前的需求。做到这一点的能力确实来自大量的经验(和痛苦)。


7

我花了一些时间对设计的总体方向进行前瞻性思考-并不是太多,但足以基本勾勒出高层次的概述。然后,我遵循一种基于故事的敏捷方法,该方法使用TDD为各个故事开发解决方案。当我通过TDD进行实施时,我会牢记高级概述,或者(a)指导我的特定实现遵循高级概述,或者(b)根据(基于)重构(并改进)高级理解/指导我在测试/实施过程中学到的东西。

我认为不做任何预先计划是一个错误,但是做太多事情可能是一个更大的错误。我想让我尽可能多地从整体上指导我,然后让设计按照我在应用程序开发方面的想法一直有机地发展。通过使用TDD,我发现设计本身被迫遵循更好的设计原则(去耦,单一职责等),并且与变更相比,如果我尝试预先构想整体并使开发适合其中,则更具延展性。


3

好的设计可以适应未来的变化,因此绝对值得。考虑UNIX操作系统及其“一切都是文件原理”。做出该设计决定不是为了满足当前的需求,而是为了将来的需求。人们不禁思索基于“敏捷”设计的操作系统的外观。


2

您要处理的事情与重用有关(即,您现在要处理的问题的普遍化,以便将来可以重用工作(代码))。我已经说过了,我会再次链接到它。

我想我已经听到其他人说了些什么:

我第一次解决问题。当我第一次重复解决方案时,我会注意到它。当我再次重复时,我进行重构。


2

设计为“现在+1”。这意味着,解决眼前的问题,并构建足够的功能,以便下次他们要求更改时,您已经完成了一半(或更多),并且可以选择a)立即解决它,然后稍后进行重构,或b)再次解决“现在+ 1”(“现在”完成一半)

这确实取决于项目,简而言之,经验将教您“ +1”是什么。


1

YAGNI的理念,“您将不再需要它”可以用(从本文中)总结:

那些主张使用YAGNI方法的人认为,目前暂时没有必要但将来可能会编写代码的诱惑有以下缺点:

  • 花在添加,测试或改进必要功能上的时间。
  • 必须调试,记录和支持新功能。
  • 任何新功能都会限制将来的操作,因此现在不必要的功能可能会阻止以后实现必要的功能。
  • 在实际需要该功能之前,很难完全定义其功能并对其进行测试。如果未正确定义和测试新功能,即使最终需要它,也可能无法正常工作。
  • 它导致代码膨胀;该软件变得越来越大,越来越复杂。
  • 除非有规范和某种版本控制,否则使用该功能的程序员可能不知道该功能。
  • 添加新功能可能会建议其他新功能。如果还实施了这些新功能,则可能会导致滚雪球效应的滚雪球效应。

0

我坚信要为眼前的问题进行设计,而不是通过试图猜测所有需要满足的情况来夸大您的设计,因为“总有一天我们可能会需要它”。

基本上,给出特定要求的列表,然后针对该要求进行设计,但这并不意味着您不应该:

  • 使设计的各个方面可配置,而不是对解决方案中的这些方面进行硬编码。通过在运行时传递的参数或在启动时(或在HUP之后)通过外部配置读取。
  • 将代码加上魔术数字,
  • 避免看一看是否已经可以重复使用的内容,可能是在调整现有解决方案以提供适合于现有情况以及新要求的方法之后。

设计“可能的期货”的主要问题是您总是在猜测。可能会进行有根据的猜测,但是“当推到推挤时”仍然只是一系列猜测。

通过这样做,您也很可能会挤压您的解决方案以适合一般情况,而不是解决您的已知要求所定义的特定问题。

那是什么意思 “当你只有锤子时,一切都开始看起来像钉子。”

我希望每次听到有人说:“但是这种解决方案更适合我们将来可能遇到的一般情况,所以我为此付出了一定的代价。”

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.