code-simplification
简化代码以提高清晰度。适用于在不改变行为的前提下重构代码以提高可读性时。当代码可以运行、但阅读、维护或扩展起来比应有的难度更高时使用。当审查已积累不必要复杂度的代码时使用。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
简化代码以提高清晰度。适用于在不改变行为的前提下重构代码以提高可读性时。当代码可以运行、但阅读、维护或扩展起来比应有的难度更高时使用。当审查已积累不必要复杂度的代码时使用。
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Manage git submodules for the learning-open-code mono-repo. Use when the user wants to: (1) Add a new git submodule — auto-detect or specify the category (open-ai-skills/open-sdd/open-ai-agent/open-ai-desktop/open-knowledge/open-productivity/open-java/open-trading/open-data), record the tracking branch in .gitmodules, clone the repo, and update README.md index. (2) Sync all existing submodules to their configured branches (git fetch + checkout branch + pull). (3) Update the root README.md with an up-to-date index of all synced projects grouped by category. (4) Initialize submodules after git clone — when open-*/ directories are empty or git submodule status returns nothing, guide through the full SOP (git submodule update --init --recursive [--remote]). Trigger keywords: submodule, git submodule, 子模块, add submodule, sync submodule, update submodule, submodule branch, README index, 更新索引, clone, init, 初始化子模块, submodule init, 拉取子模块.
对开源项目进行穷尽式教学文档生成——从宏观架构到微观实现的五层分级讲解,使用 Goal Loop 算法自主驱动完整代码覆盖。所有具体教学内容生成必须激活 `.agents/skills/teach/SKILL.md`。触发条件:用户要求"完整学习某个项目"、"生成项目架构文档"、"从入口到落地讲清楚每个功能"、"代码考古"、"源码分析"、或指定一个项目目录/仓库要求全面教学。
使用并行子 agent 为模块生成多个截然不同的接口设计。当用户想要设计 API、探索接口选项、比较模块形态,或提到 "设计两次" 时使用。
交互式 QA 会话,用户以对话方式报告 bug 或问题,agent 将其录入 GitHub Issue。在后台探索代码库以获取上下文和领域语言。当用户想要报告 bug、做 QA、以对话方式录入 issue,或提及 "QA session" 时使用。
通过用户访谈创建包含微小提交的详细重构计划,并将其录入 GitHub Issue。当用户想要规划重构、创建重构 RFC,或将重构分解为安全的渐进步骤时使用。
从当前对话中提取 DDD 风格的通用语言词汇表,标记歧义并提出规范术语。保存到 UBIQUITOUS_LANGUAGE.md。当用户想要定义领域术语、构建词汇表、固化术语、创建通用语言,或提到 "领域模型" 或 "DDD" 时使用。
| name | code-simplification |
| description | 简化代码以提高清晰度。适用于在不改变行为的前提下重构代码以提高可读性时。当代码可以运行、但阅读、维护或扩展起来比应有的难度更高时使用。当审查已积累不必要复杂度的代码时使用。 |
灵感来源于 Claude Code Simplifier 插件。在此适配为适用于任何 AI 编程 agent 的模型无关、流程驱动的技能。
通过降低复杂度来简化代码,同时精确保持原有行为。目标不是更少的行数——而是让代码更易于阅读、理解、修改和调试。每次简化都必须通过一个简单的检验:"新团队成员是否能比原始版本更快地理解这段代码?"
不适用场景:
不要改变代码的功能——只改变它的表达方式。所有输入、输出、副作用、错误行为和边界情况必须保持不变。如果不确定某个简化是否保持了行为,就不要做。
每次变更前自问:
→ 对于每个输入,是否产生相同的输出?
→ 是否保持相同的错误行为?
→ 是否保持相同的副作用和执行顺序?
→ 所有现有测试是否在不修改的情况下仍然通过?
简化意味着让代码与代码库更加一致,而不是强加外部偏好。在简化之前:
1. 阅读 CLAUDE.md / 项目约定
2. 研究邻近代码如何处理类似模式
3. 匹配项目的以下风格:
- import 顺序和模块系统
- 函数声明风格
- 命名约定
- 错误处理模式
- 类型注解深度
破坏项目一致性的简化不是简化——是折腾。
当紧凑版本需要思考才能解析时,显式的代码优于紧凑的代码。
// UNCLEAR: Dense ternary chain
const label = isNew ? 'New' : isUpdated ? 'Updated' : isArchived ? 'Archived' : 'Active';
// CLEAR: Readable mapping
function getStatusLabel(item: Item): string {
if (item.isNew) return 'New';
if (item.isUpdated) return 'Updated';
if (item.isArchived) return 'Archived';
return 'Active';
}
// UNCLEAR: Chained reduces with inline logic
const result = items.reduce((acc, item) => ({
...acc,
[item.id]: { ...acc[item.id], count: (acc[item.id]?.count ?? 0) + 1 }
}), {});
// CLEAR: Named intermediate step
const countById = new Map<string, number>();
for (const item of items) {
countById.set(item.id, (countById.get(item.id) ?? 0) + 1);
}
简化有一个失败模式:过度简化。注意以下陷阱:
默认只简化最近修改的代码。避免对无关代码进行顺手重构,除非明确要求扩大范围。无限定范围的简化会在 diff 中产生噪音,并带来意外的回归风险。
在变更或移除任何东西之前,先理解它为什么存在。这就是切斯特顿之栏:如果你在路中间看到一道围栏却不理解它为什么在那里,不要拆掉它。先理解原因,然后判断原因是否仍然成立。
简化之前先回答:
- 这段代码的职责是什么?
- 什么调用了它?它调用了什么?
- 边界情况和错误路径有哪些?
- 是否有定义其预期行为的测试?
- 它为什么会写成这样?(性能?平台约束?历史原因?)
- 检查 git blame:这段代码的原始上下文是什么?
如果你无法回答这些问题,说明还没准备好进行简化。先去阅读更多上下文。
扫描以下模式——每个都是具体信号,而非模糊的坏味道:
结构复杂度:
| 模式 | 信号 | 简化方式 |
|---|---|---|
| 深层嵌套(3+ 层) | 控制流难以跟踪 | 将条件提取为卫语句或辅助函数 |
| 长函数(50+ 行) | 承担了多个职责 | 拆分为具有描述性名称的聚焦函数 |
| 嵌套三元表达式 | 需要心理解析栈 | 替换为 if/else 链、switch 或查表对象 |
| 布尔参数标志 | doThing(true, false, true) | 替换为选项对象或独立函数 |
| 重复的条件判断 | 多处出现相同的 if 检查 | 提取为命名良好的谓词函数 |
命名与可读性:
| 模式 | 信号 | 简化方式 |
|---|---|---|
| 泛型名称 | data、result、temp、val、item | 重命名为描述内容的名称:userProfile、validationErrors |
| 缩写名称 | usr、cfg、btn、evt | 使用完整单词,除非缩写是通用的(id、url、api) |
| 误导性名称 | 名为 get 的函数却修改了状态 | 重命名以反映实际行为 |
| 解释"是什么"的注释 | // increment counter 在 count++ 上方 | 删除注释——代码已经足够清晰 |
| 解释"为什么"的注释 | // Retry because the API is flaky under load | 保留——这些承载了代码无法表达的意图 |
冗余:
| 模式 | 信号 | 简化方式 |
|---|---|---|
| 重复逻辑 | 相同的 5+ 行代码出现在多处 | 提取为共享函数 |
| 死代码 | 不可达分支、未使用的变量、被注释掉的代码块 | 移除(确认确实已死后) |
| 不必要的抽象 | 未增加任何价值的包装器 | 内联包装器,直接调用底层函数 |
| 过度设计的模式 | 工厂的工厂、只有一种策略的策略模式 | 替换为简单直接的方式 |
| 冗余的类型断言 | 强制转换为已经被推断出的类型 | 移除断言 |
一次只做一项简化。每次变更后运行测试。将重构变更与功能或 bug 修复变更分开提交。 一个既重构又添加功能的 PR 应该是两个 PR——将它们拆分。
每次简化:
1. 进行变更
2. 运行测试套件
3. 如果测试通过 → 提交(或继续下一个简化)
4. 如果测试失败 → 回退并重新评估
避免将多个简化批量合并成一次未测试的变更。如果出了问题,你需要知道是哪个简化引起的。
500 行规则: 如果某次重构需要触及超过 500 行代码,请投入自动化(codemod、sed 脚本、AST 转换)而非手工修改。这种规模的手工编辑容易出错,审查起来也令人疲倦。
所有简化完成后,退后一步整体评估:
对比前后:
- 简化后的版本是否真正更容易理解?
- 是否引入与代码库不一致的新模式?
- diff 是否干净且适合审查?
- 团队成员是否会同意这次变更?
如果"简化后"的版本更难理解或审查,请回退。并非每次简化尝试都能成功。
// SIMPLIFY: Unnecessary async wrapper
// Before
async function getUser(id: string): Promise<User> {
return await userService.findById(id);
}
// After
function getUser(id: string): Promise<User> {
return userService.findById(id);
}
// SIMPLIFY: Verbose conditional assignment
// Before
let displayName: string;
if (user.nickname) {
displayName = user.nickname;
} else {
displayName = user.fullName;
}
// After
const displayName = user.nickname || user.fullName;
// SIMPLIFY: Manual array building
// Before
const activeUsers: User[] = [];
for (const user of users) {
if (user.isActive) {
activeUsers.push(user);
}
}
// After
const activeUsers = users.filter((user) => user.isActive);
// SIMPLIFY: Redundant boolean return
// Before
function isValid(input: string): boolean {
if (input.length > 0 && input.length < 100) {
return true;
}
return false;
}
// After
function isValid(input: string): boolean {
return input.length > 0 && input.length < 100;
}
# SIMPLIFY: Verbose dictionary building
# Before
result = {}
for item in items:
result[item.id] = item.name
# After
result = {item.id: item.name for item in items}
# SIMPLIFY: Nested conditionals with early return
# Before
def process(data):
if data is not None:
if data.is_valid():
if data.has_permission():
return do_work(data)
else:
raise PermissionError("No permission")
else:
raise ValueError("Invalid data")
else:
raise TypeError("Data is None")
# After
def process(data):
if data is None:
raise TypeError("Data is None")
if not data.is_valid():
raise ValueError("Invalid data")
if not data.has_permission():
raise PermissionError("No permission")
return do_work(data)
// SIMPLIFY: Verbose conditional rendering
// Before
function UserBadge({ user }: Props) {
if (user.isAdmin) {
return <Badge variant="admin">Admin</Badge>;
} else {
return <Badge variant="default">User</Badge>;
}
}
// After
function UserBadge({ user }: Props) {
const variant = user.isAdmin ? 'admin' : 'default';
const label = user.isAdmin ? 'Admin' : 'User';
return <Badge variant={variant}>{label}</Badge>;
}
// SIMPLIFY: Prop drilling through intermediate components
// Before — consider whether context or composition solves this better.
// This is a judgment call — flag it, don't auto-refactor.
| 借口 | 事实 |
|---|---|
| "已经能用了,不需要改" | 难以阅读但能工作的代码,在出问题时也难以修复。现在简化可以为你将来的每次变更节省时间。 |
| "行数越少越简单" | 1 行的嵌套三元表达式并不比 5 行的 if/else 更简单。简单关乎理解速度,而非行数。 |
| "我顺便把这段无关的代码也简化一下" | 未限定范围的简化在 diff 中产生噪音,并在你没打算改的代码中引入回归风险。保持专注。 |
| "类型定义已经足够文档化了" | 类型记录的是结构,不是意图。命名良好的函数比类型签名更好地解释了"为什么"。 |
| "这个抽象以后可能会用到" | 不要保留推测性的抽象。如果现在没用到,它只是没有价值的复杂度。移除它,需要时再加回来。 |
| "原作者肯定有原因" | 也许有。检查 git blame —— 应用切斯特顿之栏。但累积的复杂度常常没有原因,只是赶时间迭代的残留。 |
| "我顺便在加这个功能时重构一下" | 把重构和功能开发分开。混合的变更更难审查、更难回退、更难以在历史中理解。 |
完成一轮简化后: