mcpField
Y
yagni

yagni

github.com/jordancoin开发11134 次安装35 周前更新
代码仓库

关于 yagni

面向软件开发者的 YAGNI 原则技能,主张围绕当前需求实现功能,等实际需求出现后再抽象。内容包括判断规则、反模式、边界说明和代码审查清单。

主要功能

  1. 01聚焦当前需求
  2. 02三次重复后再抽象
  3. 03移除推测性代码
  4. 04避免过早扩展机制
  5. 05代码审查检查清单

适用场景

  1. 01评估是否需要新增抽象
  2. 02审查配置项和未使用代码路径
  3. 03处理重复代码与抽象时机

MCP 相关

说明建议在框架相关问题上使用 context7 MCP 或网页搜索;若存在 `.agents/stack-context.md`,应先读取。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jordancoin/codingskills --skill yagni

安装后在 Claude Code 中输入/yagni确认已加载。

详细介绍

YAGNI — 你不会需要它

应用前

如果 .agents/stack-context.md 存在,请先阅读。使用检测到的技术栈所惯用的模式来应用这一原则。对于特定框架的细节,请使用 context7 MCP 或网页搜索,不要猜测。

原则

不要为假设中的未来需求构建功能。只构建当前所需的内容,并在实际需求出现时再重构。

这在生产环境中为何重要

投机性代码是意外复杂性的头号来源。你添加的每个“以防万一”的抽象、配置选项或扩展点都有实际成本:必须理解、测试、维护和调试。未使用的代码路径最危险——它们会悄无声息地腐朽,给人测试覆盖率良好的错觉,还会扩大 Bug 的影响范围。

过早泛化比重复更糟。重复显而易见,之后也容易修复。而错误的抽象很难撤销,因为其他代码会逐渐依赖它。

规则

  1. 解决眼前的问题。 如果只有一个用例,就为这一个用例编写代码。不是两个,也不是考虑“以后万一”。
  2. 重复三次,再抽象。 第一次遇到时,直接编写代码。第二次遇到时,留意重复。第三次遇到时,提取模式——此时你已有足够的信息来设计正确的抽象。
  3. 删除投机性的代码路径。 如果某个功能标志从未启用过、某个配置选项从未更改过,或某个参数从未传入默认值以外的值,就删除它。
  4. 不要为一个插件构建插件系统。 只有在当前已有多个具体实现时,接口、注册表和扩展点才有其必要性。
  5. 不确定时先做原型。 如果你不确定是否需要某项功能,可以在分支中快速试验。不要把投机性的基础设施合并到主分支。

反模式

  • 添加“以提高灵活性”的参数,但它们始终只接收一个值
  • 只有两个组件时,它们本可以直接互相调用,却仍构建事件系统
  • 创建只有一个具体实现的抽象基类
  • 为永远不会改变的值编写配置文件
  • 添加“以后可能需要”的数据库列
  • 未衡量是否存在性能问题就实现缓存
  • 本可以通过函数调用解决,却构建微服务

示例

-- YAGNI violation: generic "processor" for one operation
class DataProcessor:
    def __init__(self, strategy, validator, transformer, output_format):
        self.strategy = strategy
        ...

-- Actually needed: one function
def process_csv_upload(file):
    rows = parse_csv(file)
    validate_rows(rows)
    save_to_db(rows)
-- YAGNI violation: premature abstraction
interface INotificationService
class EmailNotificationService implements INotificationService
class SMSNotificationService implements INotificationService  // "we might need this"
class PushNotificationService implements INotificationService  // "just in case"

-- Actually needed: you only send emails today
def send_welcome_email(user):
    mailer.send(to=user.email, template="welcome")

适用边界

  • YAGNI 不意味着忽略架构。 良好的结构(关注点分离、清晰的模块边界)并非投机——它能降低未来改动的成本。YAGNI 针对的是未使用的功能,而不是良好的设计。
  • YAGNI 不意味着跳过错误处理。 处理已知的故障模式(网络错误、无效输入、磁盘已满)并非投机——这些情况会在生产环境中发生。
  • YAGNI 不意味着避免零成本的可扩展性。 如果让代码具备可扩展性不需要任何成本(例如,使用映射而不是 switch 语句),就这么做。YAGNI 针对的是成本高昂的抽象。
  • 与 DRY 的取舍: 有时应优先遵循 YAGNI——保留两个相似但不完全相同的函数,也好过过早地用错误的抽象将它们统一起来。

代码审查清单

  • 此更改是否引入了当前需求未覆盖的代码路径?
  • 是否存在当前只有一个可能取值的参数、配置或选项?
  • 能否用直接实现替代此抽象,而不损失功能?
  • 此接口/trait/协议是否有多个具体实现作为依据?
  • 对于当前范围,是否有更简单的方案可行?

相关技能

  • kiss:问题在于复杂性而非投机时
  • solid:设计有充分依据的抽象时
  • dry:决定是否提取模式时(YAGNI 建议等到出现 3 次)

评论

支持 Markdown