“您将不需要它”和“现在总比没有好”如何一起玩?


17

当我提高设计的干燥度时,我经常发现自己拥抱“现在比没有更好”。通常,我发现我需要在其他知识体系的背景下,对一种知识建立对一个权威位置的理解。因此,我倾向于将系统设计为“现在”。

相反,尽管有一定的机会我不需要它,但这种做法仍使我提前建立了。

这两种模式如何相符?

您使用什么方法来确保它们表现良好?

您如何一起教他们又不引起混乱?


2
三思而后行。但是犹豫的人迷路了。
mmyers

Answers:


26

我也尝试着想得更远,但通常不在代码中。我集思广益并记笔记,希望组织得井井有条,以便我可以再次参考。

在代码方面,我更倾向于“您将不需要它”,但是在设计方面,“现在总比没有好”。

在开始构建新系统时,很想立即构建所有内容,但它也会削弱您的动力和士气。我倾向于考虑整体设计,并试图通过它来画一条直线-提出一个端到端的骨架架构,并首先应用合理的设计原理来构建它,以便以后我可以对其进行改进和重构以实现新功能。

建立可以工作的最简单的系统端到端表示;首先,然后您需要反思。这往往有助于使所有那些模糊的“假设”问题明确化,并帮助您确定下一步需要做什么。


3
+1在设计中留出一定的空间并不意味着您必须在最初就将其中的大部分构建出来。太多的人屈从于绝对的要求,即在提出请求之前不应考虑任何事情,并使自己陷入比没有客户输入任何东西的情况下糟糕得多的情况。
条例草案

9

YAGNI意味着事情在需要完成时而不是之前完成。这并不意味着他们永远不会完成,除非永远不需要它们。这意味着您只做能给客户带来直接业务价值的事情。立即的商业价值意味着对每个客户和每个项目都有主观性。

无论哪种情况,使用YAGNI 都不会丢失任何东西

在另一种情况下,您会浪费时间来编写永不使用的代码,为永不使用的代码编写测试,为永不使用的代码编写文档以及对永不使用的代码进行维护,这使人们不知所措,并且一旦被使用,就会产生恶作剧。

如果我正在研究原型/概念证明或应用程序的1.0版本,那么我不需要进行设计就可以扩展到Facebook级别。地狱,直到我开始发现自己拥有这种流量,我才需要将设计扩展到Facebook的水平。

您认为扎克伯格设计的第一个Facebook版本可以扩展到5亿用户吗?不,他设计并制造了它,只是想要它要做而已。如果他从第一天开始就为5亿用户设计出瀑布,那么Facebook可能永远不会发布。

做事的实际方法是他的做法。他开始使用PHP和MySQL,然后根据业务价值进行了重新设计和重写,将其扩展到数百万个用户具有巨大的业务价值,但在第0天就没有。在第0天,只是启动某项东西便具有了巨大的业务价值。

计划重新设计和重写。这与计划厨房水槽的想法不同,从不实际开发或交付任何有用的有用东西。

生命周期规划代码库并进行重写是敏捷的,并且是面向未来的。试图提出一些不确定的“灵活”目标只是每次都以失败告终。您无需任何浪费就可以进行业务价值的设计,而不是如愿地梦想着永远不会使用的功能。


2
如果您的设计不好(例如不灵活),那么使用YAGNI可能会损失很多。
EricSchaefer 2011年

1
@EricSchaefer-如果它满足了目标并为企业提供了价值,并且您没有投入大量时间,那么您将它丢掉的损失就比永远不会交付永远无法完成并交付的神奇的无限灵活的系统要少如果确实如此,那将是配置方面的噩梦。

6

PythonZen方式说:

现在总比没有好。尽管从来没有比现在更好的了。

这个想法不是因为现在可以定义一些东西。现在需要吗?

  • 是的:现在就做!
  • 否:不要这样做!等待需要!亚尼!

这种情况不太明显的情况是在重构情况下。我是否应该每次都使用DRY?答案尚不清楚,因为在某些情况下,应用DRY的成本(花费的时间)多于重复。但是,从长远来看,在没有技术/性能原因之前应用DRY总是好的。

因此,YAGNI直到您做完,然后现在就做。不要等!


3

我认为他们根本不会一起玩。我认为您要么倾斜,要么倾斜。我倾向于YAGNI。

但是,就其价值而言,我不同意第二点建议,即“现在总比没有好”。如果一项要求很重要,那么必须完成。因此,“永远”是不可能的。如果这不重要,那么“现在”就不会更好-“从不”会更好。

只是我的两分钱。


现在的百万美元问题是:“重要”是什么意思?
Aaronaught 2011年

1
“重要”表示这是一项验收测试。
kindall 2011年

“重要”意味着客户不在时会大声疾呼。
保罗·内森

2
重要提示表示客户不在场时不付款。
Christopher Mahan

@Christopher,这可以解释为鼓励非专业主义。例如,即使客户不知道它是什么并且肯定不会在付款前进行测试,防止SQL注入也很重要。
彼得·泰勒

2

这两种模式如何相符?

它们是正交的,彼此无关。

您使用什么方法来确保它们表现良好?

嗯 他们俩都做吗?还有什么呢?

您如何一起教他们又不引起混乱?

YAGNI描述了用户看到的功能。你不需要花哨的东西。

现在比从来没有描述过这个过程更好。现在编写测试。现在编写代码。不要浪费时间考虑设计替代方案。建立一些东西,而不是谈论建立一些东西。


2

如果“从不”表示“不是现在”,则说明您的设计存在缺陷。

您做出的本地决策应该对系统的其余部分透明。
例如,如果您有一个component CookieSource,它需要根据您的一些输入参数CookieFactory将其将CookieRecipes其转换Cookies为,则CookieSource不必,因此也不必取决于如何CookieFactory实现和CookieRecipes表示。
如果CookieFactory实际上是a Bakery,则可以Recipe根据需要考虑任何因素Pastry。并且除非您需要该功能,否则无需实现它。而且,世界上没有理由不能在以后添加它,除非它们之间CookieSource和使用的服务之间没有明确的抽象障碍。

在构建软件时,请根据需要添加功能,并尽量不要将自己锁定在做出的任何决定中。而是将决策锁定为适当的抽象


1

我发现的最简单的解决方案是在预先编写代码时期待更改。当我将一些布尔值传递给函数时,通常会尽快将其更改为一个标志/枚举,这样它a)更具可读性,b)易于扩展。类似地,如果我注意到我在需要闻的地方传递了一堆参数,我通常会创建一个特殊的结构。希望是YAGNI,但如果您在某个时候这样做,它不会立即破坏所有用户,并且“艰巨的工作”已经完成。通常,您也可以只添加一些注释,例如/ *将来的添加内容放在此处* /左右,因此很明显尚未实现,但这里是添加它的地方。这通常最有帮助,因为我后来发现接口重构最耗时。


我原则上喜欢这种哲学,但实际上,我发现迁移带来的痛苦足以让我三思。您是否发现迁移模型妨碍了预期的变化?
贾斯汀·迈尔斯·霍尔姆斯

这种方法的好处是,更改的痛苦较小。仍然涉及很多工作。我不确定您对迁移模型的含义-我肯定会支持YAGNI,但我会为最坏的情况做准备:)
Anteru 2011年

0

在设计时会考虑将来的扩展,但是在需要它们之前不要实现这些扩展。

想到的示例是Netflix首次启动时,每个帐户只能有一个队列。他们后来入侵了对多个队列的支持。因为从一开始就不是这样设计的,所以维护变得越来越困难,因此他们决定停止使用该功能。在客户骚动之后,他们忍住了子弹,并进行了重新设计以正确集成多个队列。

如果一开始的人允许他们以后可能想要多个队列,那么他们本可以为自己节省很多长期的痛苦,而只需要很少的短期工作。他们不必立即真正实现多个队列,只需确保他们曾经这样做就不需要大量的重写或无法维护的黑客。

从表面上看,这似乎需要像算命先生一样的能力来预测未来的需求,但是在实践中,当一个好的程序员注意到他正在对某些东西或数据库表进行硬编码时,这样的事情往往会浮出水面。正在收集很多仅含糊的相关列。

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.