incremental-implementation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Incremental Implementation

增量式实现

Overview

概述

Build in thin vertical slices — implement one piece, test it, verify it, then expand. Never attempt to implement an entire feature in one pass. Each increment should leave the system in a working, testable state. This is the execution discipline that makes large features manageable.
采用细粒度垂直切片的方式构建——先实现一个模块,对其进行测试、验证,再逐步扩展。切勿尝试一次性实现完整功能。每次增量都应保证系统处于可运行、可测试的状态。这是让大型功能开发变得可控的执行准则。

When to Use

适用场景

  • Implementing any multi-file change
  • Building a new feature from a task breakdown
  • Refactoring existing code
  • Any time you're tempted to write more than ~100 lines before testing
When NOT to use: Single-file, single-function changes where the scope is already minimal.
  • 实现涉及多个文件的变更
  • 基于任务拆分构建新功能
  • 重构现有代码
  • 当你打算编写超过约100行代码才进行测试时
不适用场景: 仅涉及单个文件、单个函数的最小范围变更。

The Increment Cycle

增量循环

┌──────────────────────────────────────┐
│                                      │
│   Implement ──→ Test ──→ Verify ──┐  │
│       ▲                           │  │
│       └───── Commit ◄─────────────┘  │
│              │                       │
│              ▼                       │
│          Next slice                  │
│                                      │
└──────────────────────────────────────┘
For each slice:
  1. Implement the smallest complete piece of functionality
  2. Test — run the test suite (or write a test if none exists)
  3. Verify — confirm the slice works as expected (tests pass, build succeeds, manual check)
  4. Commit — save your progress with a descriptive message
  5. Move to the next slice — carry forward, don't restart
┌──────────────────────────────────────┐
│                                      │
│   Implement ──→ Test ──→ Verify ──┐  │
│       ▲                           │  │
│       └───── Commit ◄─────────────┘  │
│              │                       │
│              ▼                       │
│          Next slice                  │
│                                      │
└──────────────────────────────────────┘
对于每个切片:
  1. 实现 最小的完整功能模块
  2. 测试 —— 运行测试套件(如果没有测试则编写测试)
  3. 验证 —— 确认该切片功能符合预期(测试通过、构建成功、人工检查)
  4. 提交 —— 用描述性信息保存你的进度
  5. 进入下一切片 —— 继续推进,而非从头开始

Slicing Strategies

切片策略

Vertical Slices (Preferred)

垂直切片(推荐)

Build one complete path through the stack:
Slice 1: Create a task (DB + API + basic UI)
    → Tests pass, user can create a task via the UI

Slice 2: List tasks (query + API + UI)
    → Tests pass, user can see their tasks

Slice 3: Edit a task (update + API + UI)
    → Tests pass, user can modify tasks

Slice 4: Delete a task (delete + API + UI + confirmation)
    → Tests pass, full CRUD complete
Each slice delivers working end-to-end functionality.
构建贯穿整个技术栈的完整路径:
Slice 1: Create a task (DB + API + basic UI)
    → Tests pass, user can create a task via the UI

Slice 2: List tasks (query + API + UI)
    → Tests pass, user can see their tasks

Slice 3: Edit a task (update + API + UI)
    → Tests pass, user can modify tasks

Slice 4: Delete a task (delete + API + UI + confirmation)
    → Tests pass, full CRUD complete
每个切片都能交付可端到端运行的功能。

Contract-First Slicing

契约优先切片

When backend and frontend need to develop in parallel:
Slice 0: Define the API contract (types, interfaces, OpenAPI spec)
Slice 1a: Implement backend against the contract + API tests
Slice 1b: Implement frontend against mock data matching the contract
Slice 2: Integrate and test end-to-end
当前端和后端需要并行开发时:
Slice 0: Define the API contract (types, interfaces, OpenAPI spec)
Slice 1a: Implement backend against the contract + API tests
Slice 1b: Implement frontend against mock data matching the contract
Slice 2: Integrate and test end-to-end

Risk-First Slicing

风险优先切片

Tackle the riskiest or most uncertain piece first:
Slice 1: Prove the WebSocket connection works (highest risk)
Slice 2: Build real-time task updates on the proven connection
Slice 3: Add offline support and reconnection
If Slice 1 fails, you discover it before investing in Slices 2 and 3.
优先处理风险最高或最不确定的模块:
Slice 1: Prove the WebSocket connection works (highest risk)
Slice 2: Build real-time task updates on the proven connection
Slice 3: Add offline support and reconnection
如果切片1失败,你可以在投入切片2和3之前就发现问题。

Implementation Rules

实现规则

Rule 0: Simplicity First

规则0:简洁优先

Before writing any code, ask: "What is the simplest thing that could work?"
After writing code, review it against these checks:
  • Can this be done in fewer lines?
  • Are these abstractions earning their complexity?
  • Would a staff engineer look at this and say "why didn't you just..."?
  • Am I building for hypothetical future requirements, or the current task?
SIMPLICITY CHECK:
✗ Generic EventBus with middleware pipeline for one notification
✓ Simple function call

✗ Abstract factory pattern for two similar components
✓ Two straightforward components with shared utilities

✗ Config-driven form builder for three forms
✓ Three form components
Three similar lines of code is better than a premature abstraction. Implement the naive, obviously-correct version first. Optimize only after correctness is proven with tests.
在编写任何代码之前,先问自己:“最简单的可行方案是什么?”
编写完代码后,对照以下检查项进行评审:
  • 能否用更少的代码实现?
  • 这些抽象是否真的有必要?
  • 资深工程师看到这段代码会不会说“你为什么不直接……”?
  • 我是在为假设的未来需求构建,还是针对当前任务?
SIMPLICITY CHECK:
✗ Generic EventBus with middleware pipeline for one notification
✓ Simple function call

✗ Abstract factory pattern for two similar components
✓ Two straightforward components with shared utilities

✗ Config-driven form builder for three forms
✓ Three form components
三段相似的代码比过早的抽象更好。先实现直观、明显正确的版本。只有在通过测试验证正确性后再进行优化。

Rule 0.5: Scope Discipline

规则0.5:范围约束

Touch only what the task requires.
Do NOT:
  • "Clean up" code adjacent to your change
  • Refactor imports in files you're not modifying
  • Remove comments you don't fully understand
  • Add features not in the spec because they "seem useful"
  • Modernize syntax in files you're only reading
If you notice something worth improving outside your task scope, note it — don't fix it:
NOTICED BUT NOT TOUCHING:
- src/utils/format.ts has an unused import (unrelated to this task)
- The auth middleware could use better error messages (separate task)
→ Want me to create tasks for these?
仅修改任务要求的内容。
切勿:
  • “清理”与你的变更无关的代码
  • 在未修改的文件中重构导入语句
  • 删除你不完全理解的注释
  • 添加需求中没有的“看起来有用”的功能
  • 在仅需阅读的文件中更新语法
如果你注意到任务范围外有值得改进的地方,记录下来——不要立即修复:
NOTICED BUT NOT TOUCHING:
- src/utils/format.ts has an unused import (unrelated to this task)
- The auth middleware could use better error messages (separate task)
→ Want me to create tasks for these?

Rule 1: One Thing at a Time

规则1:一次只做一件事

Each increment changes one logical thing. Don't mix concerns:
Bad: One commit that adds a new component, refactors an existing one, and updates the build config.
Good: Three separate commits — one for each change.
每次增量只修改一个逻辑单元。不要混合关注点:
错误示例: 一次提交同时添加新组件、重构现有组件并更新构建配置。
正确示例: 三次独立提交——每个变更对应一次提交。

Rule 2: Always Compilable

规则2:始终保持可编译

After each increment, the project must build and existing tests must pass. Never leave the codebase in a broken state between slices.
每次增量完成后,项目必须能构建成功,且现有测试必须通过。切勿在切片之间让代码库处于损坏状态。

Rule 3: Feature Flags for Incomplete Features

规则3:为未完成功能使用Feature Flags

If a feature isn't ready for users but you need to merge increments:
typescript
// Feature flag for work-in-progress
const ENABLE_TASK_SHARING = process.env.FEATURE_TASK_SHARING === 'true';

if (ENABLE_TASK_SHARING) {
  // New sharing UI
}
This lets you merge small increments to the main branch without exposing incomplete work.
如果功能尚未准备好面向用户,但你需要合并增量代码:
typescript
// Feature flag for work-in-progress
const ENABLE_TASK_SHARING = process.env.FEATURE_TASK_SHARING === 'true';

if (ENABLE_TASK_SHARING) {
  // New sharing UI
}
这样你可以将小的增量合并到主分支,而不会暴露未完成的功能。

Rule 4: Safe Defaults

规则4:安全默认值

New code should default to safe, conservative behavior:
typescript
// Safe: disabled by default, opt-in
export function createTask(data: TaskInput, options?: { notify?: boolean }) {
  const shouldNotify = options?.notify ?? false;
  // ...
}
新代码应默认采用安全、保守的行为:
typescript
// Safe: disabled by default, opt-in
export function createTask(data: TaskInput, options?: { notify?: boolean }) {
  const shouldNotify = options?.notify ?? false;
  // ...
}

Rule 5: Rollback-Friendly

规则5:易于回滚

Each increment should be independently revertable:
  • Additive changes (new files, new functions) are easy to revert
  • Modifications to existing code should be minimal and focused
  • Database migrations should have corresponding rollback migrations
  • Never delete something in one commit and replace it in the same commit — separate them
每次增量都应能独立回滚:
  • 增量式变更(新增文件、新增函数)易于回滚
  • 对现有代码的修改应尽可能少且集中
  • 数据库迁移应包含对应的回滚迁移
  • 切勿在一次提交中删除内容并替换它——分开进行

Working with Agents

与Agent协作

When directing an agent to implement incrementally:
"Let's implement Task 3 from the plan.

Start with just the database schema change and the API endpoint.
Don't touch the UI yet — we'll do that in the next increment.

After implementing, run `npm test` and `npm run build` to verify
nothing is broken."
Be explicit about what's in scope and what's NOT in scope for each increment.
当指导Agent进行增量式实现时:
"Let's implement Task 3 from the plan.

Start with just the database schema change and the API endpoint.
Don't touch the UI yet — we'll do that in the next increment.

After implementing, run `npm test` and `npm run build` to verify
nothing is broken."
要明确每个增量的包含范围和排除范围。

Increment Checklist

增量检查清单

After each increment, verify:
  • The change does one thing and does it completely
  • All existing tests still pass (
    npm test
    )
  • The build succeeds (
    npm run build
    )
  • Type checking passes (
    npx tsc --noEmit
    )
  • Linting passes (
    npm run lint
    )
  • The new functionality works as expected
  • The change is committed with a descriptive message
每次增量完成后,验证以下内容:
  • 变更仅针对一件事且已完整实现
  • 所有现有测试仍通过(
    npm test
  • 构建成功(
    npm run build
  • 类型检查通过(
    npx tsc --noEmit
  • 代码检查通过(
    npm run lint
  • 新功能符合预期
  • 变更已用描述性信息提交

Common Rationalizations

常见自我辩解及真相

RationalizationReality
"I'll test it all at the end"Bugs compound. A bug in Slice 1 makes Slices 2-5 wrong. Test each slice.
"It's faster to do it all at once"It feels faster until something breaks and you can't find which of 500 changed lines caused it.
"These changes are too small to commit separately"Small commits are free. Large commits hide bugs and make rollbacks painful.
"I'll add the feature flag later"If the feature isn't complete, it shouldn't be user-visible. Add the flag now.
"This refactor is small enough to include"Refactors mixed with features make both harder to review and debug. Separate them.
自我辩解真相
“我会最后一起测试”漏洞会累积。切片1中的漏洞会导致切片2-5全部出错。要测试每个切片。
“一次性完成更快”感觉上更快,但一旦出问题,你无法在500行变更中找到问题所在。
“这些变更太小,没必要单独提交”小提交没有成本。大提交会隐藏漏洞,且回滚痛苦。
“我之后再加Feature Flag”如果功能未完成,就不应让用户看到。现在就添加Flag。
“这个重构很小,可以一起做”重构与功能混合会让两者都更难评审和调试。分开进行。

Red Flags

危险信号

  • More than 100 lines of code written without running tests
  • Multiple unrelated changes in a single increment
  • "Let me just quickly add this too" scope expansion
  • Skipping the test/verify step to move faster
  • Build or tests broken between increments
  • Large uncommitted changes accumulating
  • Building abstractions before the third use case demands it
  • Touching files outside the task scope "while I'm here"
  • Creating new utility files for one-time operations
  • 编写超过100行代码却未运行测试
  • 单次增量包含多个无关变更
  • “我顺便加一下这个”的范围扩张
  • 为了加快进度跳过测试/验证步骤
  • 切片之间构建或测试失败
  • 累积大量未提交的变更
  • 在第三个用例出现前就构建抽象
  • 顺便修改任务范围外的文件
  • 为一次性操作创建新的工具文件

Verification

最终验证

After completing all increments for a task:
  • Each increment was individually tested and committed
  • The full test suite passes
  • The build is clean
  • The feature works end-to-end as specified
  • No uncommitted changes remain
完成任务的所有增量后:
  • 每个增量都已单独测试并提交
  • 完整测试套件通过
  • 构建无错误
  • 功能按需求端到端正常运行
  • 无未提交的变更