07-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-代码模式提炼

07 代码模式提炼:从实现中抽象通用模式

这是《Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人》系列的第 7 篇。前几篇我们蒸馏了"文档"和"知识",这一篇蒸馏"智慧"——从重复的代码实现里,抽象出可复用的模式。如果说知识摘要是"知道什么",那模式库就是"知道怎么做"。


一、为什么代码模式值得提炼

写代码的人都知道一个现象:同一个问题,会在代码里出现很多次。可能是同一个 API 的调用方式,可能是同一个校验逻辑,可能是同一个状态处理流程。

这些重复不是偶然——它们背后是团队反复验证过的解决方案。但问题是:

  • 这些方案散落在代码各处,没有名字、没有文档
  • 新成员只能靠"翻代码"才能发现"原来大家都是这么写的"
  • 方案背后的"为什么"(为什么这么写)完全丢失

模式提炼的价值:把"散落的重复"变成"有名字、有文档、有理由"的模式库。让团队从"每次重新发明"变成"查库复用"。


二、重复代码与相似实现识别

2.1 用 jscpd 检测重复代码

jscpd(JavaScript Copy/Paste Detector)是检测重复代码的利器:

# 安装
npm install -g jscpd

# 检测重复代码
jscpd src/ --min-lines 5 --min-tokens 50

# 输出 HTML 报告
jscpd src/ --output report.html --format html

输出示例:

Found 23 clones in 12 files.
Total tokens: 45600
Clones tokens: 8900 (19.5%)

Clones:
  src/api/model-api.ts:10-35
  src/api/export-api.ts:15-40
  (similarity: 92%)

重复率解读

  • < 5%:健康,无需处理
  • 5% ~ 15%:有重复,值得关注
  • 15%:重复严重,是模式提炼的富矿

2.2 用 grep 找"相似实现"

有些重复不是逐字复制,而是"结构相似"。用 grep 找相似模式:

# 找重复的 try-catch 结构
grep -rn "try {" src/ --include="*.ts" | wc -l

# 找重复的 loading 状态处理
grep -rn "isLoading\|loading.value" src/ --include="*.ts" --include="*.vue" | wc -l

# 找重复的 API 调用模式
grep -rn "axios.get\|http.get" src/ --include="*.ts" | head -20

2.3 用 git log 找"反复修改"的代码

# 找出被反复修改的函数(可能是"问题模式")
git log --oneline -S "handleError" -- src/

# 找出反复出现的"临时修复"
git log --oneline --grep="hotfix\|临时\|workaround" -- src/

反复修改的代码往往是"半成品模式"——团队一直在用,但一直没把它做好。这类代码提炼成模式后,价值最大。


三、模式抽象:从具体实现到通用模式

3.1 模式抽象四步法

把重复实现抽象成模式,分四步:

  1. 收集:找出所有相似实现
  2. 对比:找出共同点和差异点
  3. 抽象:提取共同结构,参数化差异点
  4. 命名:给模式起一个有意义的名字

3.2 示例:从重复代码到模式

第一步:收集(发现 3 处相似实现)

// src/api/model-api.ts
export async function fetchModels() {
  const res = await http.get('/models');
  if (res.code !== 0) {
    throw new Error(res.message);
  }
  return res.data;
}

// src/api/export-api.ts
export async function fetchExports() {
  const res = await http.get('/exports');
  if (res.code !== 0) {
    throw new Error(res.message);
  }
  return res.data;
}

// src/api/user-api.ts
export async function fetchUsers() {
  const res = await http.get('/users');
  if (res.code !== 0) {
    throw new Error(res.message);
  }
  return res.data;
}

第二步:对比(共同点 vs 差异点)

维度共同点差异点
请求方式都是 GET
响应处理都检查 code,非 0 抛错
返回数据都返回 res.data
接口路径/models、/exports、/users

第三步:抽象(提取通用结构,参数化差异点)

// src/utils/request.ts
export async function fetchList<T>(path: string): Promise<T> {
  const res = await http.get(path);
  if (res.code !== 0) {
    throw new Error(res.message);
  }
  return res.data as T;
}

// 使用
const models = await fetchList<Model[]>('/models');
const exports = await fetchList<ExportItem[]>('/exports');
const users = await fetchList<User[]>('/users');

第四步:命名(给模式起名)

模式名:统一请求封装(Unified Request Wrapper)
适用场景:所有"GET 请求 + 统一响应格式"的接口调用
做法:封装 fetchList<T>(path),统一处理响应码和错误
理由:避免重复的错误处理逻辑,保证错误处理一致

3.3 模式文档模板

每个模式都应该有标准文档:

# 模式:统一请求封装(Unified Request Wrapper)

## 适用场景
所有"GET 请求 + 统一响应格式"的接口调用

## 问题
每个 API 函数都重复写"检查 code、抛错、返回 data"的逻辑

## 解决方案
封装通用函数,参数化接口路径

## 代码示例
(见上文 fetchList 实现)

## 使用方式
const models = await fetchList<Model[]>('/models');

## 注意事项
- 仅适用于统一响应格式的接口
- 非标准响应需单独处理

## 来源
- src/api/model-api.ts、export-api.ts、user-api.ts(2022-03 提炼)

四、模式库建设

4.1 模式库目录结构

patterns/
├── README.md              # 模式库索引
├── 01-请求封装/
│   ├── unified-request.md # 模式文档
│   └── example.ts         # 示例代码
├── 02-状态管理/
│   └── store-factory.md
├── 03-表单处理/
│   └── form-validation.md
└── 04-错误处理/
    └── error-boundary.md

4.2 模式库索引

# 模式库索引

## 请求层
- [统一请求封装](01-请求封装/unified-request.md) — GET + 统一响应
- [分页请求](01-请求封装/pagination.md) — 列表分页加载

## 状态层
- [Store 工厂](02-状态管理/store-factory.md) — 统一创建 Pinia store
- [缓存模式](02-状态管理/cache.md) — 请求结果缓存

## 交互层
- [表单校验](03-表单处理/form-validation.md) — 统一表单校验
- [空态处理](03-表单处理/empty-state.md) — 列表空数据展示

## 异常层
- [错误边界](04-错误处理/error-boundary.md) — 组件级错误兜底
- [重试模式](04-错误处理/retry.md) — 请求失败自动重试

4.3 模式库的维护

模式库不是"写完就完",需要持续维护:

# 定期重新检测重复代码,发现新模式
jscpd src/ --min-lines 5 --min-tokens 50

# 检查模式是否被实际使用
grep -rn "fetchList" src/ --include="*.ts" | wc -l

维护原则

  • 新模式出现 → 提炼并入库
  • 模式不再使用 → 标记废弃
  • 模式被大量使用 → 考虑提升为公共库

五、输出模式库

5.1 模式库汇总表

# 模式库汇总

| 模式 | 分类 | 使用次数 | 提炼时间 | 状态 |
|------|------|---------|---------|------|
| 统一请求封装 | 请求层 | 12 | 2022-03 | 活跃 |
| 分页请求 | 请求层 | 8 | 2022-05 | 活跃 |
| Store 工厂 | 状态层 | 6 | 2022-08 | 活跃 |
| 表单校验 | 交互层 | 9 | 2022-11 | 活跃 |
| 错误边界 | 异常层 | 4 | 2023-02 | 活跃 |
| 重试模式 | 异常层 | 2 | 2023-06 | 实验 |

5.2 模式库的用途

模式库是蒸馏流程的方法论沉淀

  • 给 08 决策记录:模式的选择/放弃是决策的素材
  • 给 09 知识图谱:模式是图谱的"方法"节点
  • 给 10 工具链:高频模式可固化为代码生成模板
  • 给 12 虚拟人化:模式库是虚拟人 skills 的核心来源

六、小结

这一篇的核心收获:

  1. 识别重复:用 jscpd 检测重复代码,用 grep 找相似实现,用 git log 找反复修改的代码。
  2. 模式抽象四步法:收集 → 对比 → 抽象 → 命名,从具体实现到通用模式。
  3. 模式文档:每个模式有标准文档(适用场景、问题、方案、示例、注意事项、来源)。
  4. 模式库建设:分类归档 + 索引 + 持续维护。
  5. 输出模式库:一份可复用的方法论沉淀,是虚拟人 skills 的核心来源。

下一篇,我们记录决策:[08 决策记录:用 ADR 固化架构决策](08-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-决策记录.md)——把"为什么这么设计"用 ADR 固化下来,防止知识流失。


上一篇:[06 文档蒸馏:从 issue、PR、README 提炼知识](06-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-文档蒸馏.md)
下一篇:[08 决策记录:用 ADR 固化架构决策](08-Git 仓库蒸馏术:从代码仓库到 OpenClaw 虚拟人-决策记录.md)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leoZ231

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值