10

YAGNI “原则”指出,您不应该在需要之前专注于提供功能,因为无论如何“您不会需要它”。

无论如何,我通常倾向于在任何规则之上使用常识,但有时我觉得如果你有充分的理由,过度设计或未来证明某些东西是有用的,即使你可能永远不会使用它。

我现在手头的实际情况或多或少是这样的:

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

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

那么,你的想法是什么?我应该只为专有协议进行设计,然后将重构、接口提取等留到我真正需要的时候,还是应该现在就考虑(不是那么远)未来进行设计?

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

4

8 回答 8

8

YAGNI 应用于代码的原因是更改成本低。使用良好、重构良好的代码在以后添加功能通常很便宜。这与说构造不同。

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

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

于 2009-02-16T09:22:15.557 回答
7

恕我直言

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

如果您非常确定地知道某事即将出现并在以后添加它会很痛苦,那么要关闭它,不要成为鸵鸟……为它设计。
例如,我知道在产品发货之前需要诊断日志。一个月后添加日志代码将比今天在我编写每个函数时添加它更加努力......所以这将是我会覆盖 YAGNI 的情况,即使我现在不需要日志。

另见:T. & M. Poppendieck 的精益书籍更能解释上述第 2 条的困境。

于 2009-02-16T09:13:45.030 回答
5

很好地构建程序(抽象等)并不是 YAGNI 所适用的。你总是想很好地组织你的代码。

澄清一下,我认为您目前的困境是由于过度应用 YAGNI 造成的。以这样一种方式构建您的代码,以便您拥有一个可重用的库来使用此协议,这只是一种良好的编程实践。YAGNI 不适用。

于 2009-02-16T09:02:33.997 回答
3

我认为当你想学习一些东西时,YAGNI 可能是不合适的 :) YAGNI 对专业人士有好处,但不适合学生。当你想学习时,你总是需要它。

于 2009-02-16T08:57:06.460 回答
3

我认为这非常简单明了:

当您完全确定您将需要它时违反 YAGNI

于 2009-02-16T09:18:44.067 回答
2

我不会担心的。你意识到“YAGNI”的事实意味着你已经在务实地思考。

我想说,不管这里发布了什么,从统计上讲,你比没有以同样方式分析他们的实践的人更有可能提出更好的代码。

于 2009-02-16T09:02:07.930 回答
0

我同意 Gishu 和 Nick 的观点。

稍后设计协议的一部分通常会导致诸如“该死,我应该这样做,现在我不得不使用这种丑陋的解决方法”这样的想法

但这也取决于谁将与此协议交互。
如果您的控制两端,并且它们将同时更改版本,您可以随时重构协议,就像使用普通代码接口一样。

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

于 2009-02-16T13:58:44.473 回答
0

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

这里有几个:

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

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

断言、调试检查、故障保护等。这些代码实际上并不是您的应用程序正常工作所必需的,但它有助于确保您的代码现在和将来在进行修订时正常工作。

于 2009-08-06T03:27:37.307 回答