code-simplification

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Simplification

代码简化

Inspired by the Claude Code Simplifier plugin. Adapted here as a model-agnostic, process-driven skill for any AI coding agent.
灵感来自Claude Code Simplifier 插件。此处改编为适用于任何AI编码Agent的、与模型无关的、流程驱动型技能。

Overview

概述

Simplify code by reducing complexity while preserving exact behavior. The goal is not fewer lines — it's code that is easier to read, understand, modify, and debug. Every simplification must pass a simple test: "Would a new team member understand this faster than the original?"
在保留代码原有行为的前提下简化代码,降低复杂度。目标并非减少代码行数,而是让代码更易于阅读、理解、修改和调试。每一处简化都必须通过一个简单测试:"新团队成员理解这段代码的速度会比原代码更快吗?"

When to Use

使用场景

  • After a feature is working and tests pass, but the implementation feels heavier than it needs to be
  • During code review when readability or complexity issues are flagged
  • When you encounter deeply nested logic, long functions, or unclear names
  • When refactoring code written under time pressure
  • When consolidating related logic scattered across files
  • After merging changes that introduced duplication or inconsistency
When NOT to use:
  • Code is already clean and readable — don't simplify for the sake of it
  • You don't understand what the code does yet — comprehend before you simplify
  • The code is performance-critical and the "simpler" version would be measurably slower
  • You're about to rewrite the module entirely — simplifying throwaway code wastes effort
  • 功能开发完成且测试通过后,但实现方式显得过于繁琐时
  • 代码审查中发现可读性或复杂度问题时
  • 遇到深度嵌套逻辑、过长函数或命名模糊的代码时
  • 重构在时间压力下编写的代码时
  • 整合分散在多个文件中的相关逻辑时
  • 合并引入重复或不一致问题的代码变更后
不适用于以下场景:
  • 代码本身已简洁易读——不要为了简化而简化
  • 你尚未理解代码的功能——先理解再简化
  • 代码对性能要求极高,"简化版"会导致可测量的性能下降时
  • 你即将完全重写该模块——简化临时代码纯属浪费精力

The Five Principles

五大原则

1. Preserve Behavior Exactly

1. 完全保留原有行为

Don't change what the code does — only how it expresses it. All inputs, outputs, side effects, error behavior, and edge cases must remain identical. If you're not sure a simplification preserves behavior, don't make it.
ASK BEFORE EVERY CHANGE:
→ Does this produce the same output for every input?
→ Does this maintain the same error behavior?
→ Does this preserve the same side effects and ordering?
→ Do all existing tests still pass without modification?
不要改变代码的功能——只优化其表达方式。所有输入、输出、副作用、错误行为和边缘情况必须保持一致。如果不确定某一简化操作是否能保留原有行为,请勿执行。
每次变更前请确认:
→ 该变更是否对所有输入都产生相同输出?
→ 该变更是否保持了相同的错误处理行为?
→ 该变更是否保留了相同的副作用和执行顺序?
→ 所有现有测试是否无需修改即可通过?

2. Follow Project Conventions

2. 遵循项目约定

Simplification means making code more consistent with the codebase, not imposing external preferences. Before simplifying:
1. Read CLAUDE.md / project conventions
2. Study how neighboring code handles similar patterns
3. Match the project's style for:
   - Import ordering and module system
   - Function declaration style
   - Naming conventions
   - Error handling patterns
   - Type annotation depth
Simplification that breaks project consistency is not simplification — it's churn.
简化意味着让代码与代码库更一致,而非强加外部偏好。开始简化前:
1. 阅读CLAUDE.md / 项目约定文档
2. 研究相邻代码如何处理类似模式
3. 匹配项目的风格规范:
   - 导入顺序和模块系统
   - 函数声明风格
   - 命名约定
   - 错误处理模式
   - 类型注解深度
破坏项目一致性的简化不是简化——而是无意义的变更。

3. Prefer Clarity Over Cleverness

3. 清晰优先于巧妙

Explicit code is better than compact code when the compact version requires a mental pause to parse.
typescript
// 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';
}
typescript
// 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);
}
当紧凑代码需要额外思考才能解析时,显式代码优于紧凑代码。
typescript
// 不清晰:密集的三元表达式链
const label = isNew ? 'New' : isUpdated ? 'Updated' : isArchived ? 'Archived' : 'Active';

// 清晰:可读性强的映射函数
function getStatusLabel(item: Item): string {
  if (item.isNew) return 'New';
  if (item.isUpdated) return 'Updated';
  if (item.isArchived) return 'Archived';
  return 'Active';
}
typescript
// 不清晰:包含内联逻辑的链式reduce
const result = items.reduce((acc, item) => ({
  ...acc,
  [item.id]: { ...acc[item.id], count: (acc[item.id]?.count ?? 0) + 1 }
}), {});

// 清晰:命名化的中间步骤
const countById = new Map<string, number>();
for (const item of items) {
  countById.set(item.id, (countById.get(item.id) ?? 0) + 1);
}

4. Maintain Balance

4. 保持平衡

Simplification has a failure mode: over-simplification. Watch for these traps:
  • Inlining too aggressively — removing a helper that gave a concept a name makes the call site harder to read
  • Combining unrelated logic — two simple functions merged into one complex function is not simpler
  • Removing "unnecessary" abstraction — some abstractions exist for extensibility or testability, not complexity
  • Optimizing for line count — fewer lines is not the goal; easier comprehension is
简化存在一种失败模式:过度简化。请注意以下陷阱:
  • 过度内联——移除赋予概念名称的辅助函数会使调用处更难理解
  • 合并无关逻辑——将两个简单函数合并为一个复杂函数并非简化
  • 移除"不必要的"抽象——有些抽象是为了扩展性或可测试性而存在,并非为了增加复杂度
  • 以行数为优化目标——更少的行数不是目的;更易理解才是

5. Scope to What Changed

5. 聚焦变更范围

Default to simplifying recently modified code. Avoid drive-by refactors of unrelated code unless explicitly asked to broaden scope. Unscoped simplification creates noise in diffs and risks unintended regressions.
默认只简化最近修改的代码。除非明确要求扩大范围,否则避免对无关代码进行顺带重构。无范围限制的简化会在差异对比中产生噪音,并可能导致意外的回归问题。

The Simplification Process

简化流程

Step 1: Understand Before Touching (Chesterton's Fence)

步骤1:先理解再修改(切斯特顿栅栏原则)

Before changing or removing anything, understand why it exists. This is Chesterton's Fence: if you see a fence across a road and don't understand why it's there, don't tear it down. First understand the reason, then decide if the reason still applies.
BEFORE SIMPLIFYING, ANSWER:
- What is this code's responsibility?
- What calls it? What does it call?
- What are the edge cases and error paths?
- Are there tests that define the expected behavior?
- Why might it have been written this way? (Performance? Platform constraint? Historical reason?)
- Check git blame: what was the original context for this code?
If you can't answer these, you're not ready to simplify. Read more context first.
在更改或移除任何内容之前,先理解其存在的原因。这就是切斯特顿栅栏原则:如果你看到道路上有一道栅栏却不理解它的用途,不要拆除它。先理解原因,再决定该原因是否仍然适用。
开始简化前,请回答:
- 这段代码的职责是什么?
- 哪些代码调用它?它调用哪些代码?
- 有哪些边缘情况和错误路径?
- 是否有定义预期行为的测试?
- 它为什么会被写成这样?(性能原因?平台限制?历史原因?)
- 查看git blame:这段代码的原始上下文是什么?
如果无法回答这些问题,说明你还没准备好进行简化。先阅读更多上下文信息。

Step 2: Identify Simplification Opportunities

步骤2:识别简化机会

Scan for these patterns — each one is a concrete signal, not a vague smell:
Structural complexity:
PatternSignalSimplification
Deep nesting (3+ levels)Hard to follow control flowExtract conditions into guard clauses or helper functions
Long functions (50+ lines)Multiple responsibilitiesSplit into focused functions with descriptive names
Nested ternariesRequires mental stack to parseReplace with if/else chains, switch, or lookup objects
Boolean parameter flags
doThing(true, false, true)
Replace with options objects or separate functions
Repeated conditionalsSame
if
check in multiple places
Extract to a well-named predicate function
Naming and readability:
PatternSignalSimplification
Generic names
data
,
result
,
temp
,
val
,
item
Rename to describe the content:
userProfile
,
validationErrors
Abbreviated names
usr
,
cfg
,
btn
,
evt
Use full words unless the abbreviation is universal (
id
,
url
,
api
)
Misleading namesFunction named
get
that also mutates state
Rename to reflect actual behavior
Comments explaining "what"
// increment counter
above
count++
Delete the comment — the code is clear enough
Comments explaining "why"
// Retry because the API is flaky under load
Keep these — they carry intent the code can't express
Redundancy:
PatternSignalSimplification
Duplicated logicSame 5+ lines in multiple placesExtract to a shared function
Dead codeUnreachable branches, unused variables, commented-out blocksRemove (after confirming it's truly dead)
Unnecessary abstractionsWrapper that adds no valueInline the wrapper, call the underlying function directly
Over-engineered patternsFactory-for-a-factory, strategy-with-one-strategyReplace with the simple direct approach
Redundant type assertionsCasting to a type that's already inferredRemove the assertion
扫描以下模式——每种模式都是具体信号,而非模糊的代码异味:
结构复杂度:
模式信号简化方式
深度嵌套(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行以上代码提取为共享函数
死代码不可达分支、未使用变量、注释掉的代码块删除(确认确实是死代码后)
不必要的抽象无价值的包装器内联包装器,直接调用底层函数
过度设计的模式工厂的工厂、只有一种策略的策略模式替换为简单直接的实现方式
冗余的类型断言转换为已推断出的类型移除断言

Step 3: Apply Changes Incrementally

步骤3:逐步应用变更

Make one simplification at a time. Run tests after each change. Submit refactoring changes separately from feature or bug fix changes. A PR that refactors and adds a feature is two PRs — split them.
FOR EACH SIMPLIFICATION:
1. Make the change
2. Run the test suite
3. If tests pass → commit (or continue to next simplification)
4. If tests fail → revert and reconsider
Avoid batching multiple simplifications into a single untested change. If something breaks, you need to know which simplification caused it.
The Rule of 500: If a refactoring would touch more than 500 lines, invest in automation (codemods, sed scripts, AST transforms) rather than making the changes by hand. Manual edits at that scale are error-prone and exhausting to review.
每次只进行一处简化。每次变更后运行测试。将重构变更与功能或修复变更分开提交。 同时包含重构和新增功能的PR应拆分为两个PR。
对于每一处简化:
1. 进行变更
2. 运行测试套件
3. 如果测试通过 → 提交(或继续下一处简化)
4. 如果测试失败 → 回滚并重新考虑
避免将多处简化合并为一个未测试的变更。如果出现问题,你需要知道是哪一处简化导致的。
500行规则: 如果重构会修改超过500行代码,请使用自动化工具(codemods、sed脚本、AST转换)而非手动修改。手动处理这种规模的代码容易出错,且审查难度大。

Step 4: Verify the Result

步骤4:验证结果

After all simplifications, step back and evaluate the whole:
COMPARE BEFORE AND AFTER:
- Is the simplified version genuinely easier to understand?
- Did you introduce any new patterns inconsistent with the codebase?
- Is the diff clean and reviewable?
- Would a teammate approve this change?
If the "simplified" version is harder to understand or review, revert. Not every simplification attempt succeeds.
完成所有简化后,退一步评估整体效果:
对比简化前后:
- 简化后的版本是否真的更易于理解?
- 是否引入了与代码库不一致的新模式?
- 代码差异是否清晰且易于审查?
- 队友是否会批准此变更?
如果"简化版"更难理解或审查,请回滚。并非所有简化尝试都能成功。

Language-Specific Guidance

特定语言指导

TypeScript / JavaScript

TypeScript / JavaScript

typescript
// 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;
}
typescript
// 简化:不必要的async包装
// 简化前
async function getUser(id: string): Promise<User> {
  return await userService.findById(id);
}
// 简化后
function getUser(id: string): Promise<User> {
  return userService.findById(id);
}

// 简化:冗长的条件赋值
// 简化前
let displayName: string;
if (user.nickname) {
  displayName = user.nickname;
} else {
  displayName = user.fullName;
}
// 简化后
const displayName = user.nickname || user.fullName;

// 简化:手动构建数组
// 简化前
const activeUsers: User[] = [];
for (const user of users) {
  if (user.isActive) {
    activeUsers.push(user);
  }
}
// 简化后
const activeUsers = users.filter((user) => user.isActive);

// 简化:冗余的布尔返回
// 简化前
function isValid(input: string): boolean {
  if (input.length > 0 && input.length < 100) {
    return true;
  }
  return false;
}
// 简化后
function isValid(input: string): boolean {
  return input.length > 0 && input.length < 100;
}

Python

Python

python
undefined
python
undefined

SIMPLIFY: Verbose dictionary building

简化:冗长的字典构建

Before

简化前

result = {} for item in items: result[item.id] = item.name
result = {} for item in items: result[item.id] = item.name

After

简化后

result = {item.id: item.name for item in items}
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")
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)
undefined
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)
undefined

React / JSX

React / JSX

tsx
// 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.
tsx
// 简化:冗长的条件渲染
// 简化前
function UserBadge({ user }: Props) {
  if (user.isAdmin) {
    return <Badge variant="admin">Admin</Badge>;
  } else {
    return <Badge variant="default">User</Badge>;
  }
}
// 简化后
function UserBadge({ user }: Props) {
  const variant = user.isAdmin ? 'admin' : 'default';
  const label = user.isAdmin ? 'Admin' : 'User';
  return <Badge variant={variant}>{label}</Badge>;
}

// 简化:通过中间组件传递属性
// 简化前——考虑context或组合是否能更好地解决此问题。
// 这需要判断——标记出来,不要自动重构。

Common Rationalizations

常见合理化借口

RationalizationReality
"It's working, no need to touch it"Working code that's hard to read will be hard to fix when it breaks. Simplifying now saves time on every future change.
"Fewer lines is always simpler"A 1-line nested ternary is not simpler than a 5-line if/else. Simplicity is about comprehension speed, not line count.
"I'll just quickly simplify this unrelated code too"Unscoped simplification creates noisy diffs and risks regressions in code you didn't intend to change. Stay focused.
"The types make it self-documenting"Types document structure, not intent. A well-named function explains why better than a type signature explains what.
"This abstraction might be useful later"Don't preserve speculative abstractions. If it's not used now, it's complexity without value. Remove it and re-add when needed.
"The original author must have had a reason"Maybe. Check git blame — apply Chesterton's Fence. But accumulated complexity often has no reason; it's just the residue of iteration under pressure.
"I'll refactor while adding this feature"Separate refactoring from feature work. Mixed changes are harder to review, revert, and understand in history.
借口实际情况
"代码能运行,没必要修改"难以阅读的可用代码在出现问题时也难以修复。现在进行简化能为未来的每一次变更节省时间。
"行数越少越简单"1行嵌套三元表达式并不比5行if/else简单。简单性关乎理解速度,而非行数。
"我顺便把这段无关代码也简化一下"无范围限制的简化会产生嘈杂的代码差异,并可能在你无意修改的代码中引入回归问题。保持专注。
"类型注释已经自文档化了"类型注释记录结构,而非意图。命名清晰的函数比类型签名更能解释"为什么"。
"这个抽象以后可能有用"不要保留推测性的抽象。如果现在没用,那就是无价值的复杂度。移除它,需要时再重新添加。
"原作者肯定有理由这么写"可能有。查看git blame——应用切斯特顿栅栏原则。但累积的复杂度往往没有理由,只是在时间压力下迭代产生的残留。
"我在添加功能时顺便重构"将重构与功能开发分开。混合变更更难审查、回滚,且在历史记录中更难理解。

Red Flags

警示信号

  • Simplification that requires modifying tests to pass (you likely changed behavior)
  • "Simplified" code that is longer and harder to follow than the original
  • Renaming things to match your preferences rather than project conventions
  • Removing error handling because "it makes the code cleaner"
  • Simplifying code you don't fully understand
  • Batching many simplifications into one large, hard-to-review commit
  • Refactoring code outside the scope of the current task without being asked
  • 简化操作需要修改测试才能通过(你很可能改变了代码行为)
  • "简化版"代码比原代码更长、更难理解
  • 按照个人偏好而非项目约定重命名
  • 为了"让代码更简洁"而移除错误处理
  • 简化你尚未完全理解的代码
  • 将多处简化合并为一个大型、难以审查的提交
  • 未经要求就重构当前任务范围外的代码

Verification

验证环节

After completing a simplification pass:
  • All existing tests pass without modification
  • Build succeeds with no new warnings
  • Linter/formatter passes (no style regressions)
  • Each simplification is a reviewable, incremental change
  • The diff is clean — no unrelated changes mixed in
  • Simplified code follows project conventions (checked against CLAUDE.md or equivalent)
  • No error handling was removed or weakened
  • No dead code was left behind (unused imports, unreachable branches)
  • A teammate or review agent would approve the change as a net improvement
完成简化后:
  • 所有现有测试无需修改即可通过
  • 构建成功且无新警告
  • 代码检查/格式化工具通过(无风格回归)
  • 每一处简化都是可审查的增量变更
  • 代码差异清晰——未混入无关变更
  • 简化后的代码遵循项目约定(已对照CLAUDE.md或等效文档检查)
  • 未移除或弱化错误处理
  • 无残留死代码(未使用的导入、不可达分支)
  • 队友或审查Agent会批准此变更,认为其是净改进