anti-over-engineering
Anti Over Engineering
概述
本 Skill 用于约束开发时的复杂度选择。 核心原则:先解决当前真实问题,再决定是否需要额外抽象。默认选择最简单、最直接、最容易解释的实现。只有当复杂度能解决今天已经存在的问题时,才允许引入它。
何时使用
- 当你想新增 wrapper、manager、factory、proxy、adapter、service layer、缓存、单例、注册表、通用配置层时
- 当你想“顺手为以后扩展一下”时
- 当你发现自己在为还没出现的第二个或第三个场景设计时
- 当你准备把框架已经能做的决策重新硬编码到业务层时
- 当你想为了“优雅”“通用”“可扩展”“看起来更专业”而多加一层时
默认决策顺序
- 先写最直接的实现。
- 只满足当前明确需求。
- 跑测试,确认它真的工作。
- 只有在出现真实重复、真实瓶颈、真实多场景差异后,才抽象。
- 抽象时只抽最低限度,不一次性把未来五种变化都做进去。
核心规则
- 默认不加层。 新增一层必须回答:如果不加,这个提交今天具体哪里会更差?
- 没有第二个真实调用方,就先别抽象通用接口。
- 没有真实性能问题,就先别加缓存、单例、池化、预加载。
- 没有真实可替换实现,就先别上工厂、策略注册表、插件机制。
- 框架已经能做的调度、路由、编排、生命周期管理,不要先手搓一套。
- 先证明重复存在,再抽公共函数。先证明结构失控,再拆更多文件。
- 当简单实现已经清楚可用时,不要为了“以后可能会变”提前泛化。
允许增加复杂度的条件
只有满足下面至少一条,才值得认真考虑增加复杂度:
- 已有重复逻辑出现两处及以上,且重复不是偶然的
- 已有明确性能瓶颈,并且有数据或调用频率支撑
- 已有两个以上真实调用场景,接口差异已稳定出现
- 已有测试、事故或维护痛点证明当前结构正在制造问题
- 用户或需求文档明确要求可配置、可扩展、可替换能力
红旗信号
出现这些想法时,先停下来:
- “先做通用一点,免得以后重构”
- “这个以后大概率会用到”
- “顺手把缓存也加了吧”
- “虽然现在只有一个实现,但先抽接口”
- “虽然现在只有一个地方用,但先做成框架”
- “这里也许以后会支持多种模式/来源/后端”
- “先把 orchestrator 写好,后面更灵活”
- “这样更优雅” 这些通常不是需求,而是想象。
常见过度设计模式
- 空包装函数:函数体只转调另一个函数,却没有新增语义或约束
- 假单例/假缓存:没有性能证据,却引入缓存生命周期复杂度
- 代理对象:只为了“看起来像对象”而增加理解成本
- 过早分层:controller -> service -> manager -> helper -> adapter,但每层都很薄
- 手写编排:框架能自动决定的流程,被业务层提前写死
- 过早 schema 化:数据结构尚未稳定,就拆出大量类型和 DTO
- 未来导向抽象:现在只有一个来源、一个模型、一个实现,却先设计成多态系统
更好的默认做法
- 先用普通函数,而不是 manager / factory / proxy
- 先直接调用,而不是空转一层 wrapper
- 先让调用关系显式,而不是提前隐藏到注册表里
- 先让代码重复一点点,而不是过早抽成难懂的公共层
- 先让数据结构贴近当前业务,而不是追求“最通用模型”
- 先把 prompt、框架、现有能力用对,而不是补一层自己的伪框架
自检问题
在提交前,问自己:
- 这层复杂度解决的是今天的什么问题?
- 不加它,代码真的会坏,还是只是没那么“高级”?
- 有没有更直接、更短、更容易解释的版本?
- 我是在响应真实需求,还是在防御想象中的未来?
- 三个月后的维护者,能不能一眼看懂这段代码为什么存在? 如果第 1 个问题回答不具体,或者第 2 个问题答案是“不会坏”,就回到更简单的实现。
常见借口
| 借口 | 现实 |
|---|---|
| 以后可能会扩展 | 以后真的扩展时再改,通常更便宜 |
| 这样更优雅 | 可读、可改、可验证,比“优雅”更重要 |
| 先抽出来避免重复 | 只有一个地方时,这不是重复 |
| 先缓存避免性能问题 | 没数据支撑的优化通常是在制造状态问题 |
| 先做成通用框架 | 现在没有多个真实场景,框架只会增加负担 |
| 先把边界设计好 | 真实边界通常来自真实变化,不来自猜测 |
一句话准则
今天没有证据,就不要为明天付复杂度成本。
More from cruldra/skills
tauri-v2
Tauri v2 项目开发助手 - 提供 CLI 项目管理、最佳实践指导和代码生成。适用于 (1) 创建和管理 Tauri v2 项目 (2) 开发桌面和移动应用 (3) 配置构建和分发流程 (4) 实现安全的前后端通信 (5) 应用架构设计和性能优化。
15pandoc
当用户需要对某个文档进行格式转换时(例如将 Markdown 转换为 DOCX、PDF、HTML 等)使用该技能。
12refine-dev
协助开发基于 Refine 框架的 React 应用。提供项目初始化、核心配置、数据提供者(Data Providers)、认证(Auth Provider)以及 UI 库集成的指导。专注于使用 shadcn/ui 构建现代化的后台管理系统。
11dri-text-analysis
使用 DRI 文本分析法(Data-Rule-Interaction)对自然语言需求描述进行逐词拆解与领域建模。将非结构化的业务需求文本降维为数据(D)、规则(R)、交互(I)三个维度的结构化架构抽象,直接产出可用于系统设计的概念表格。适用于需求分析、领域语言提取、架构设计前的文本解析,以及将长篇需求文档转化为清晰的开发任务拆解。
9vite-starter
使用 Vite 创建现代前端项目,支持 React、Vue、Svelte、Solid、Preact、Lit、Qwik 和 Vanilla JS,可选 TypeScript。当用户需要初始化新的前端项目、搭建 SPA、创建组件库、设置现代构建工具时使用此技能。触发场景:用户说"创建 vite 项目"、"新建 react/vue/svelte 应用"、"初始化前端项目"、"搭建 spa"、"用 vite 起一个项目"、"create vite project"、"new frontend app",或明确提及 Vite、HMR、快速构建工具时。
7plantuml-renderer
Use when the user wants to render PlantUML diagrams from pasted text or files that contain valid PlantUML blocks (such as .puml, .md, or .docx text content), and expects image/text output like svg, png, txt, or utxt via local Java + plantuml.jar.
7