跳至页脚内容
Iron Academy Logo
C# 常见问题

软件开发中的 YAGNI 原则:您真的需要抽象或通用代码吗?

在快节奏的软件开发世界中,开发人员往往努力通过构建未来的应用程序来适应未来的发展。 但是,正如来自 CodeOpinion.com 的 Derek Comartin 在其富有洞察力的视频"Do You Really Need That Abstraction or Generic Code?"中所告诫的那样,为推测性需求而构建往往会带来不必要的复杂性并浪费宝贵的资源。

本文将通过 Derek 对 YAGNI 原理的实际解释,利用现实世界中的例子和开发人员的经验,帮助您更好地理解 YAGNI 并将其应用到日常编码中。 无论您是专注于简洁的代码、敏捷的软件开发,还是仅仅想避免不必要的功能,Derek 的评论都能为您提供一条脚踏实地的前进之路。

什么是 YAGNI? 不要构建你不需要的东西

讨论的核心是 YAGNI 原则,即 "你不需要它"(You Aren't Gonna Need It)--这是极限编程和精益软件开发的关键概念。 正如 Derek 解释的那样,YAGNI 告诉开发人员不要实现他们认为将来会需要的特性或功能,而要专注于当前的需求。

Derek 补充了一些细微差别:虽然您应该避免编写投机性代码,但您也不希望束缚自己,影响日后的适应性。 面临的挑战是如何避免在might有用的功能上花费时间,同时还要对变化持开放态度。 这是敏捷软件和软件工程中常见的难题。

他介绍了两种常见的 YAGNI 误用情况:

1.功能规划 - 预测未来需求,现在就开始构建。

2.代码抽象 - 过早概括或抽象现有代码,猜测可能需要的其他功能。

在这两种情况下,结果通常是浪费精力、增加复杂性和功能爬升--这与良好实践和 KISS 原则(保持简单,保持愚蠢)所提倡的恰恰相反。

一个真实的例子:装运通知系统

为了说明这一点,Derek 使用了一个装运管理系统的例子,该系统会在包裹送达后向用户发送短信。 系统使用 Twilio,该功能通过处理交付事件、获取联系信息和发送消息来工作。

这种简单明了的代码开发流程可以满足当前的要求。 翻译必须简单、可测试并能带来价值。 但问题随之而来:如果我们将来想更换 SMS 提供商怎么办?

这就是许多开发人员错误引用 YAGNI 原则的地方。 他们认为,由于稍后可能会出现另一种实现**,因此现在需要对 SMS 逻辑进行抽象。 因此,他们创建了一个类似 ISmsService 的接口。

抽象:您是在为可能不存在的未来而构建吗?

Derek 对这种早期抽象提出了挑战:如果您只有一种实现方式,而且当前没有切换提供商的需求,那么为什么要抽象呢? 您正在增加不必要的复杂性,以满足未来可能永远无法实现的需求。

他进一步说明了软件工程成本。当您最终添加第二个提供商时,您会发现您的界面与 Twilio 的特定需求(如其 "发件人 "电话号码逻辑)结合得过于紧密。 突然之间,抽象变成了负担。 这就是建立在有限知识基础上的抽象往往会带来错误并使重构复杂化。

这里的主要启示是:你不是在节省时间,而是由于语境不足而构建了错误的东西。

过早实现通用:开发人员的陷阱

在计算机科学项目中,最常见的 YAGNI 违规行为之一就是在需要通用之前就将其通用化。 德里克通过另一个例子--将短信和电子邮件通知合并为一个通用的通知系统--来探讨这个问题。

为此,开发人员可能会定义一个通知类型(短信或电子邮件)、一个通用地址字段,并创建一个同时处理这两种通知的服务。 但是,这种过于抽象的设计最终会使逻辑复杂化,并产生脆弱且难以维护的条件代码路径。

这是典型的功能蠕变,也是忽视精益软件开发和稳固原则的标志。 您正在编写投机性代码,而这些代码并不能满足用户的即时需求--这在任何敏捷软件开发流程中都是个大问题。

首选扩展而非修改

与其过度工程化,Derek 建议采用最简单的解决方案:如果以后需要支持电子邮件通知,只需单独实现该功能即可。

使用事件驱动架构,每个事件都可以触发多个独立的处理程序。 例如,一个处理程序用于短信,另一个处理程序用于电子邮件。 您可以在不影响其他内容的情况下删除其中一个内容。 这种方法促进了简单性,支持不断变化的需求,并尊重关注点的分离--所有这些都符合敏捷和测试驱动开发的最佳实践。

通过构建可扩展而非过度设计的系统,您可以保持灵活性,而无需预测每一种可能的未来。 这样才能避免不必要的复杂性并保持适应性。

违反 YAGNI 的真正代价

德里克强调了构建不必要功能的实际成本:

  • 花费时间构建你从未使用过的东西

  • 增加复杂性,但不提供直接价值

  • 增加开发人员的拥有成本,他们现在不得不维护未使用或过度构建的代码

  • 由于过度工程化,出现 bug 和错误的余地更大

这符合敏捷软件开发的另一个核心原则:专注于现在就提供价值,而不是以后。

他指出,经验丰富的开发人员经常会犯一个错误,那就是相信自己对未来需求的直觉,结果却错了。 即使经验丰富,预测系统几个月后的需求也往往是一场失败的游戏。

最后的思考:语境很重要,简洁最重要

Derek 最后澄清,他并不反对设计原则或抽象。 事实上,他相信构建的系统是可以不断发展的。 但是,错误在于在没有当前理由的情况下实施了一些东西--本质上违反了 YAGNI。

他鼓励开发人员 "编写代码并实现现在就有价值的功能"。避免为了满足未来的需求而牺牲当前用户的利益。 坚持采用简洁的代码实践,并倾向于采用支持变更的设计策略,而不会将您锁定在投机性结构中。

他还邀请开发人员分享他们自己的 YAGNI 恐怖故事,在这些故事中,他们为未来而构建,却从未需要过它--这在许多项目中都很常见。

结论:将 YAGNI 应用于您的开发流程

YAGNI 原理是开发人员工具箱中最有价值的工具之一。 它符合敏捷、精益和 KISS 理念,提醒我们只构建需要的东西,而不是更多。 Derek Comartin 在他的视频中通过实际代码和开发流程示例对这一理念进行了分解,为如何有效应用 YAGNI 提供了明确的指导。

因此,下次当您想要添加一层抽象层、一个通用类或一个额外功能时,请停下来问问自己:

您是否正在解决您遇到的问题,或者您只是猜测有一天可能会出现的问题?

避免将时间花费在想象的未来上。 今天就专注于创造价值。 让您的软件保持简单、可维护并能满足实际需求。

因为您很可能并不需要它。

Hero Worlddot related to 软件开发中的 YAGNI 原则:您真的需要抽象或通用代码吗?
Hero Affiliate related to 软件开发中的 YAGNI 原则:您真的需要抽象或通用代码吗?

分享您的所爱,赚取更多收入

您为使用 .NET、C#、Java、Python 或 Node.js 的开发人员创建内容吗?将您的专业知识转化为额外收入!

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我