Update nexus wiki content
This commit is contained in:
60
wiki/concepts/PrematureAbstraction.md
Normal file
60
wiki/concepts/PrematureAbstraction.md
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: "PrematureAbstraction"
|
||||
type: concept
|
||||
tags: [engineering, code-quality, design]
|
||||
last_updated: 2026-05-02
|
||||
---
|
||||
|
||||
## Definition
|
||||
|
||||
过早抽象(PrematureAbstraction)指在实际需要提取抽象之前(通常指第三次出现之前)就引入辅助函数、类或接口的代码设计反模式。这导致引入短期内无法偿还的隐性债务。
|
||||
|
||||
## Core Rule
|
||||
|
||||
**等待第四次出现再提取。** 前三次重复出现时,保持重复代码而非提取抽象。提取的时机应基于实际的调用次数,而非"直觉上看起来应该提取"。
|
||||
|
||||
## Why Wait for the Fourth Time
|
||||
|
||||
- **第一次**:孤例,可能是一次性的特殊处理
|
||||
- **第二次**:可能是巧合,模式尚不清晰
|
||||
- **第三次**:确认存在模式,但抽象接口(参数、返回值、边界情况)尚未完全明确
|
||||
- **第四次**:抽象接口足够清晰,且维护收益开始超过抽象本身的成本
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ 过早抽象(第二次就提取)
|
||||
|
||||
```typescript
|
||||
// 第二次出现就开始提取
|
||||
const dryRun = args.includes('--dry-run');
|
||||
if (dryRun) logDryRun(records);
|
||||
|
||||
// 马上为第三次出现提取
|
||||
export function runWithMode(mode: RunMode, records: Record[]) {
|
||||
// strategy pattern introduced too early
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ 延迟抽象(第四次才提取)
|
||||
|
||||
```typescript
|
||||
// 保持三次重复
|
||||
if (dryRun) logDryRun(records);
|
||||
if (dryRun) logDryRun(items);
|
||||
if (dryRun) logDryRun(entries);
|
||||
|
||||
// 第四次出现——抽象接口完全清晰了
|
||||
export function runDry(records: Record[]) {
|
||||
return { dry: true, count: records.length };
|
||||
}
|
||||
```
|
||||
|
||||
## Connections
|
||||
|
||||
- [[engineering-minimal-change-engineer]]:最小变更工程师的核心原则之一
|
||||
- [[ScopeCreep]]:过早抽象通常是范围蔓延的表现形式
|
||||
- [[MinimalChangePrinciple]]:最小变更原则的延伸——保持重复代码直到收益明确
|
||||
|
||||
## Sources
|
||||
|
||||
- [[engineering-minimal-change-engineer]]
|
||||
Reference in New Issue
Block a user