Files
16gagent/patterns/design-patterns.md
2026-06-06 10:40:48 +08:00

155 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design Patterns — 从实际任务提取
> 来源: reflections/ + 日常开发经验
> 已验证可跨任务复用的模式
> 新增: Anti-Patterns (≥2 occurrences → promoted from reflections)
---
## Positive Patterns
## Pattern 1: Phase Isolation (阶段隔离)
**问题**: 大任务中分析、设计、实现三阶段互相干扰,导致返工
**方案**:
```
Phase 1: Analyze → 输出物: analysis/*.md (不可变)
Phase 2: Design → 输出物: plan.md (不可变)
Phase 3: Implement → 输出物: src/*.js (只读 plan.md, 不改)
```
**关键规则**: 每阶段输出物一旦完成,即标记为不可变。下一阶段只能读取,不能修改。如果发现设计缺陷,完成当前 Phase 后回头修改 plan.md。
**适用场景**: 任何需要"理解外部系统 → 设计增强方案 → 编码实现"的任务
**反模式**: 在分析源码时就开始写代码 → 分析不完整 → 后期返工
---
## Pattern 2: Self-Contained Module (自包含模块)
**问题**: 模块依赖外部库/环境,部署和测试困难
**方案**: 每个模块满足三个条件:
1. `node module.js` — CLI 独立运行
2. `require('./module')` — 库接口可被其他模块调用
3. 零必须依赖(外部依赖标记为 optional,降级到自实现)
**模板**:
```javascript
// ... implementation ...
// 库接口
module.exports = { ... };
// CLI 入口
if (require.main === module) {
main();
}
```
**实例**:
- `risk-scorer.js`: CLI + require() 双接口,零依赖
- `toml-parser.js`: 自实现,零依赖
- `ctx-compress.js`: CLI + require(),子模块均自包含
---
## Pattern 3: Strategy Dispatch (策略分发)
**问题**: 同一操作有多种策略,如何选择和扩展
**方案**:
```
1. Detect → 检测特征
2. Analyze → 分析数据
3. Recommend → 推荐策略
4. Plan → 制定执行计划
5. Execute → 执行
6. Mark → 标记结果 (CCR hash / metadata)
```
**实例**:
- SmartCrusher: 5 种压缩策略 (SmartSample/TopN/ClusterSample/TimeSeries/lossless)
- SessionRouter: 4 种路由策略 (Spawned/ReusedIdle/ReusedActive/Deferred)
- ctx_compress: 4 种压缩器 (json/log/search/diff)
**扩展方式**: 新增策略只需在策略注册表中加一个条目,不碰分发逻辑
---
## Pattern 4: Graceful Degradation (降级优先)
**问题**: 最优路径可能不可用(环境限制、数据格式不匹配)
**方案**: 永远提供降级路径
```
最优路径 → 备选路径 → 通用路径 → passthrough
```
**实例**:
- CCR Store: Redis → SQLite → InMemory → (不存, hash 仍生成)
- SmartCrusher: lossless:csv → SmartSample → passthrough:small_array
- CodeGraph 搜索: FTS5 → LIKE → 空结果
**关键**: 降级时 WARN 日志 + 明确策略名 (如 `passthrough:not_json`)
---
## Pattern 5: Three-Tier Cache (三层缓存)
**问题**: 内存缓存快但小,持久化慢但大,分布式慢但共享
**方案**:
```
L1: InMemory (500 项, 1min TTL) ← 热数据
L2: SQLite (10K 项, 5min TTL) ← 温数据
L3: Redis (可选, 分布式共享) ← 跨进程共享
```
**查询顺序**: L1 → (promote to L1) → L2 → (promote) → L3
**实例**: `src/compression/ccr-backends.js` — HybridCcrStore
---
## Anti-Patterns (from failures, ≥2 occurrences)
### AP-1: Operator Coercion Trap (2 occurrences)
**问题**: JavaScript `||``0`/`""`/`false` 当 falsy,导致排序/评分/计数逻辑出错
**症状**:
- 排序结果反转(healthy=0 排到最后)
- FK 索引计数字段被跳过
**方案**: 数值/布尔默认值用 `??`nullish coalescing),`||` 仅用于字符串默认值。
Grep `||` in scoring/ranking code.
**来源**:
- 2026-06-03: Agent Evolution FK 索引 `count || 0`
- 2026-06-05: PR-30 Cross-Agent Certification `order[status] || 6`
---
### AP-2: Generator Path Assumption (1 occurrence)
**问题**: Builder/Generator 有硬编码路径假设(如 `src/app/`),与实际 framework convention 不一致
**方案**: 生成器完成后立即跑 build smoke test,验证输出目录与 runtime 预期一致
**来源**:
- 2026-06-05: Domain Benchmark — frontend-builder 输出 `src/app/`Next.js 期望 `app/`
---
### AP-3: DDL Flat Mapping (1 occurrence)
**问题**: SQL DDL CONSTRAINT/KEY 行被解析为数据列
**方案**: DDL parser 必须有 column / constraint / index 三层分离
**来源**:
- 2026-06-05: Backend Builder — PRIMARY KEY 行泄露进 TS interface