什么时候违反YAGNI?

时间:2009-02-16 08:56:07

标签: yagni

YAGNI “原则”声明您不应该在需要之前专注于提供功能,无论如何“你根本不需要它”。

我通常倾向于使用常识高于任何规则,无论如何,但有时我认为如果你有充分的理由对过度设计或未来证明是有用的,即使你可能永远不会使用它

我现在掌握的实际情况或多或少是这样的:

我的应用程序必须通过简单的专有通信协议(OSI级别4)运行。该协议具有一组理想的特性(例如遵循NORM规范),这些特性为应用程序提供了稳健性,但并不是严格要求的(UDP多播可以接受)。

还有一个事实是,该应用程序可能(但不一定)将来会被其他客户使用,而这些客户将无法访问专有解决方案,因此需要另一种解决方案。我知道另一个客户端申请的概率很高。

那么,你的想法是什么?我应该设计专有协议并将重构,接口提取等留给我真正需要的时候,还是我现在设计思考(不是到目前为止)未来?

注意:为了清楚起见,我有兴趣听到对一般问题的所有意见(什么时候违反YAGNI)但我真的想对我目前的一些建议或想法困境:))

8 个答案:

答案 0 :(得分:8)

YAGNI适用于代码的原因是变更成本很低。通过良好的,重构良好的代码,以后添加功能通常很便宜。这与建筑不同。

在协议的情况下,稍后添加更改通常并不便宜。旧版本中断,它可能导致通信失败,以及N ^ 2测试矩阵,因为您必须针对每个其他版本测试每个版本。将其与单个代码库进行比较,其中新版本只需要自己使用。

所以在你的情况下,对于协议设计,我不推荐YAGNI。

答案 1 :(得分:7)

IMHO

  • 我先说YAGNI。使用“最简单的工作”使其无需NORM规范即可运行。
  • 接下来比较一下,在未来进行“设计更改”的成本是否显着高于,而不是现在进行更改。您目前的解决方案可逆?如果您可以在明天或几个月后轻松进行更改,请立即进行更改。如果您现在不需要做出不可逆转的设计决定..延迟到最后一个负责任的时刻(以便您有更多信息做出更好的决定)

如果你知道并且确定某些东西即将出现并且稍后添加它将会是一种痛苦,那么关闭它就不会是一种鸵鸟设计。
e.g。我知道在产品出货之前需要诊断日志。在编写每个函数之后,在一个月之后添加日志记录代码将比在今天添加日志代码要多得多...所以这将是我重写YAGNI的情况,即使我现在不需要日志。 < / p>

参见:T&amp; M. Poppendieck的精益书更能解释上面第2章子弹的困境。

答案 2 :(得分:5)

很好地构建你的程序(抽象等)不是YAGNI适用的东西。您总是希望很好地构建代码。

为了澄清,我认为你目前的困境是由于过度使用YAGNI。以这样一种方式构建代码,即使用一个可重用的库来使用该协议,这只是一种很好的编程习惯。 YAGNI不适用。

答案 3 :(得分:3)

我认为YAGNI在你想要学习的东西时可能不合适:) YAGNI对专业人士有好处,但不适合学生。如果你想学习,你将永远需要它。

答案 4 :(得分:3)

我认为这很简单明了:

当你知道这一点时违反YAGNI,完全确定,你将需要它

答案 5 :(得分:2)

我不担心。你知道“YAGNI”的事实意味着你已经在实际思考。

我会说,无论在这里发布什么,你在统计上更有可能提出更好的代码而不是那些没有以同样的方式分析他们的实践的人。

答案 6 :(得分:0)

我同意Gishu和Nick。

以后设计协议的一部分经常导致像“该死的,我应该这样做,现在我必须使用这个丑陋的解决方法”的想法

但这也取决于谁将与该协议接口。
如果您的控件同时结束,并且它们将同时更改版本,您可以随后像使用普通代码接口一样重构协议。

关于稍后执行额外的协议功能实现,我发现实现协议有助于验证其设计,因此如果需要,您至少可以想要做一个简单的生产代码示例来测试它设计是正式的。

答案 7 :(得分:0)

在某些情况下,违背YAGNI直觉是有道理的。

以下是一些:

遵循编程约定。特别是基类和接口契约。例如,如果您继承的基类提供了GetHashCode和Equals方法,则覆盖Equals但不会覆盖GetHashCode会破坏开发人员在重写Equals时应遵循的平台记录规则。即使您发现实际上不会调用GetHashCode,也应遵循此约定。没有覆盖GetHashCode是一个错误,即使没有当前的方式来激发它(除了人为的测试)。该平台的未来版本可能会引入对GetHashCode的调用。或者,另一位查看过文档的程序员(在此示例中,您继承的基类的平台文档)可能正确地期望您的代码在不检查代码的情况下遵守。另一种思考方式是所有代码和适用文档必须一致,即使是其他人编写的文档,例如平台供应商提供的文档。

支持自定义。特别是不会修改源代码的外部开发人员。您必须在代码中找出并实现合适的扩展点,以便这些开发人员可以实现从未想到的各种插件功能。不幸的是,如果有任何外部开发人员最终使用,那么您将添加一些可扩展性功能,这是相同的。 (如果可以提前与所有外部开发人员讨论可扩展性要求或使用频繁的开发/发布周期,那很好,但这对所有项目都不可行。)

断言,调试检查,故障保护等。您的应用程序实际上并不需要此类代码才能正常工作,但这有助于确保您的代码现在和将来在修订时正常运行是。