Token导航 LogoToken导航

Agent Skill · 研究检索

bookforge-duplication-removal-via-extraction(通过提取去除 Bookforge 重复项)

bookforge-duplication-removal-via-extraction 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

bookforge-duplication-removal-via-extraction 是研究检索类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为调用外部服务;许可证为 MIT-0,第三方扫描已通过,按安装量在研究检索类的 73,675 个 Skill 里排第 30,470。

总安装 2,876周安装 127GitHub Stars 公开资料未说明下载 1,040核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:bookforge-duplication-removal-via-extraction(通过提取去除 Bookforge 重复项)
来源仓库:https://github.com/quochungto/bookforge-duplication-removal-via-extraction
安装命令:
openclaw skills install bookforge-duplication-removal-via-extraction
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install bookforge-duplication-removal-via-extraction

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

通过提取共享代码消除跨类和方法的重复实现。适用于存在大量相似逻辑的遗留代码重构场景。先提取小型工具函数,再构建超类和模板方法结构。注意保持提取后代码的可读性和维护便利性。建议配合静态分析工具检测残留重复代码。

bookforge-duplication-removal-via-extraction 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install bookforge-duplication-removal-via-extraction;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要调用外部服务,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

bookforge-duplication-removal-via-extraction 怎么安装?

在终端执行 openclaw skills install bookforge-duplication-removal-via-extraction。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

bookforge-duplication-removal-via-extraction 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

bookforge-duplication-removal-via-extraction 需要什么权限?

权限级别是调用外部服务。该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

bookforge-duplication-removal-via-extraction 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

bookforge-duplication-removal-via-extraction 用的人多吗?

公开数据是累计安装 2,876 次,近一周安装 127 次,下载 1,040 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

bookforge-duplication-removal-via-extraction 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
bookforge-duplication-removal-via-extraction

通过提取去除 Bookforge 重复项 · 本页

2,876—调用外部服务MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
duplication-removal-via-extraction
description
Remove duplicated code across methods and classes by extracting small shared utilities first and letting larger structure (superclass, Template Method) emerge. Use whenever a developer says 'I'm changing the same code in multiple places', 'I'm fixing the same bug in 3 files', 'copy-pasted code everywhere', 'duplicate logic', 'DRY violation', 'same code in multiple classes', 'repeated patterns', 'shotgun surgery'. Activates for 'extract method', 'extract class', 'pull up method', 'Template Method pattern', 'superclass for duplication', 'deduplicate', 'shared utility', 'parallel classes'.
version
1.0.0
homepage
https://github.com/bookforge-ai/bookforge-skills/tree/main/books/working-effectively-with-legacy-code/skills/duplication-removal-via-extraction
metadata
{"openclaw":{"emoji":"📚","homepage":"https://github.com/bookforge-ai/bookforge-skills"}}
status
draft
source-books
title
Working Effectively with Legacy Code
authors
["Michael C. Feathers"]
chapters
[21]
domain
software-engineering
tags
[legacy-code, refactoring, software-engineering, code-quality, dry, duplication]
depends-on
execution
tier
1
mode
full
inputs
description
Two or more classes/methods with duplicated code + tests (or characterization tests) covering the duplication
tools-required
[Read, Grep, Edit, Bash]
tools-optional
[Glob]
mcps-required
[]
environment
Codebase in any OO language. Tests must exist before starting — characterization tests if none available.
discovery
goal
Consolidate duplicated code into shared structures that emerge from bottom-up extraction.
tasks
audience
roles
[software-engineer, backend-developer]
experience
intermediate
when_to_use
triggers
prerequisites
why
Tests must cover the duplication before extraction — the tests catch behavior-changing mistakes during consolidation
not_for
environment
codebase_required
true
codebase_helpful
true
works_offline
true
quality
scores
{with_skill: null, baseline: null, delta: null}
tested_at
null
eval_count
null
assertion_count
10
iterations_needed
null

Duplication Removal via Extraction

When to Use

You recognize a duplication problem: every time a rule changes, you make the same edit in multiple places. Every bug fix requires the same patch applied three times. Parallel classes drift apart over time because there is no single location of truth. Feathers calls this "I'm Changing the Same Code All Over the Place" — one of the most frustrating symptoms in legacy systems.

The instinct is often to plan a grand restructuring before touching anything. Resist it. Duplication removal does not require a reengineering effort. You can remove it in small, safe steps while doing your regular work, and the larger structure will reveal itself.

Before arriving here, run characterization-test-writing to establish a regression safety net across all the duplicated sites. Every step in this process makes a mechanical change. Without tests, you cannot distinguish "still correct" from "silently broken."

Do not use this skill when the similarity is coincidental — two classes that happen to use the same 3-line sequence but for unrelated reasons. Coupling them creates a false dependency. The test is: if one copy needed to change, would the other need to change too? If yes: real duplication. If no: coincidental similarity.

Context and Input Gathering

Collect before starting:

  1. The duplicated sites — which classes and methods contain the repeated code. Use Grep to find all occurrences if the duplication is spread across many files.
  2. Test coverage — confirm tests exist that exercise the behavior of all duplicated sites. If not, invoke characterization-test-writing first and return here.
  3. Shared type relationship — do the classes already share a common superclass or interface? If yes, pulling up is simpler. If no, you will introduce one in Step 5.
  4. Language constraints — single inheritance languages (Java, C#) mean one superclass slot. In those languages, prefer pulling up to an abstract class when a natural parent exists; use an interface when the shared behavior is incidental to identity.

Process

Step 1: Verify Test Coverage Across All Duplicated Sites

Run the test suite. Every class and method containing the duplicated code must be covered by at least one test. The tests do not need to be comprehensive — they need to catch behavior changes in the specific code you are about to move.

If any duplicated site has no test coverage: stop. Invoke characterization-test-writing for the uncovered sites, then return here.

Why tests before extraction: Each mechanical step in this process is safe in isolation but can introduce a subtle error. A miscopied variable name, a typo in the extracted method signature, a wrong access modifier — any of these silently changes behavior. Tests transform "I hope this is still correct" into "I know this is still correct."

Step 2: Identify the Smallest Duplicated Fragment

Read the duplicated methods. Do not look for the largest region of similarity — look for the smallest repeated sequence that forms a coherent unit. A two-line pair that always appears together is a valid extraction target even if the surrounding method has dozens of lines.

Feathers' heuristic: "Start small. If I can remove tiny pieces of duplication, I do those first because often it makes the big picture clearer."

Write down the fragment verbatim. Give it a candidate name. Ask: does this name describe what the fragment does, not how? If yes, you have found your extraction target.

Example: outputStream.write(field.getBytes()); outputStream.write(0x00); — always paired, always together. Name: writeField(OutputStream, String).

Step 3: Extract the Fragment to a Local Method in One Class

Pick one of the classes containing the duplication. Extract the fragment there first.

  1. Create the new private method with the candidate name.
  2. Replace every occurrence of the fragment in that class with a call to the new method.
  3. Run the tests. They must pass.

Do not touch the other class yet. The goal of this step is a passing, locally-clean change in exactly one class.

// Before (LoginCommand.write):
outputStream.write(userName.getBytes());
outputStream.write(0x00);
outputStream.write(passwd.getBytes());
outputStream.write(0x00);

// After extraction:
private void writeField(OutputStream outputStream, String field) throws Exception {
    outputStream.write(field.getBytes());
    outputStream.write(0x00);
}

// LoginCommand.write now calls:
writeField(outputStream, userName);
writeField(outputStream, passwd);

Step 4: Replicate the Same Local Method in the Other Class

Now copy the extracted method — with the identical signature — into the other class. Replace the duplicate fragment in that class with calls to the new method. Run the tests. They must pass.

At the end of this step, both classes have an identical private method with the same name, the same signature, and the same body. This is the deliberate state you are building toward: identical local copies are the precondition for a pull-up.

Why replicate before pulling up: Pulling up to a superclass before both local copies exist means you are designing top-down. That requires you to know the full structure upfront. Replicating bottom-up means you can pull up mechanically — you are not making design decisions, you are moving code that already exists.

Step 5: Introduce a Shared Superclass (If None Exists)

If the classes already share a common parent that is appropriate for the shared method, skip to Step 6.

If not, introduce one:

  1. Create an abstract superclass (e.g., Command as parent of LoginCommand and AddEmployeeCmd).
  2. Make both existing classes extend it.
  3. Do not move any code yet — only establish the type relationship.
  4. Run the tests. They must pass.

Choose a name that describes what the classes have in common, not what is convenient. If the name is awkward, the superclass boundary may be wrong.

Step 6: Pull the Method Up to the Superclass

Move the shared method from one subclass to the superclass. Delete the copy in the other subclass. Verify both subclasses now call the superclass version.

Run the tests. They must pass.

// Command (superclass) now holds:
protected void writeField(OutputStream outputStream, String field) throws Exception {
    outputStream.write(field.getBytes());
    outputStream.write(0x00);
}
// Removed from LoginCommand and AddEmployeeCmd

Step 7: Repeat for Additional Fragments

Return to Step 2. Look at the now-cleaner methods in both classes. Has the first extraction revealed more duplication? Often it has: the removed fragment was obscuring a larger pattern.

Continue extracting, replicating, and pulling up one fragment at a time. Run the tests after every step.

Step 8: Observe — Let Structure Emerge

After removing the small fragments, look at what remains. Are the write methods in both subclasses now structurally identical — same steps, different data? That is the Template Method pattern emerging:

  • Extract the variation (the "body" of the method — the part that differs per subclass) into an abstract writeBody() method.
  • Pull the invariant outer structure (header, size, command char, body, footer) up to the superclass as the single concrete write() method.
  • Each subclass only implements writeBody().

Do not design this structure upfront. Arrive at it by noticing that two method bodies are identical except for one extracted piece. The pattern is a consequence of systematic duplication removal, not a precondition for it.

Orthogonality emerges: When duplication is fully removed, each behavior has exactly one location. To change how fields are written, edit writeField. To change the message envelope, edit write. To add a new command variant, subclass and implement writeBody. This is the open/closed principle made concrete — open for extension (new subclasses), closed to modification (existing methods need not change).

Inputs

InputRequiredDescription
Duplicated code sitesYesClasses and methods containing the repeated logic
Test coverageYesPassing tests covering each duplicated site
Shared type relationshipNoWhether classes already share a parent (simplifies Step 5)

Outputs

OutputDescription
Extraction planOrdered list of fragment → local method → pull-up steps, with test runs between each
Consolidated codeShared method(s) in superclass or shared interface; thin subclasses containing only variation
Passing test suiteSame tests that existed before, still passing — behavioral proof that extraction preserved correctness

Key Principles

Start with the SMALLEST duplicated fragment, not the whole method. Large-scale deduplication is the result of many small extractions, not one large one. Small steps are reversible, verifiable, and reveal the next step naturally.

Tests MUST cover the duplication before extraction begins. Without a safety net, a mechanical step that looks correct can silently change behavior. Tests turn this process from "I believe this is safe" to "I know this is safe."

Replicate locally before pulling up. Extract to a local private method in each class first. When both local copies are identical, the pull-up is a mechanical move. This separates the "what to extract" decision from the "where to put it" decision.

Let structure emerge — do not design it upfront. Template Method, common superclasses, abstract methods — these are observations about what the code already implies, not plans imposed on the code. Arrive at them by noticing what is the same.

Coincidental similarity is not duplication. Two classes that have the same 3-line sequence for unrelated reasons should not be coupled. The test: if one copy needed to change, would the other need to change too? Same semantic intent = duplication. Shared syntax, different intent = coincidence.

After consolidation, the open/closed principle is at work. New variations become easier, not harder. A new command subclass only implements its variation. The shared mechanism is inherited. Adding a feature no longer requires changing every copy.

Examples

Example 1: LoginCommand + AddEmployeeCmd → Command Superclass

Situation: Two Java command classes both contain the repeated pair outputStream.write(field.getBytes()); outputStream.write(0x00); for every string field they write. Both classes write header, command char, fields, footer — same structure, different fields.

Step 2 — Smallest fragment: The two-line write-and-terminate pair. Name: writeField(OutputStream, String).

Step 3 — Extract locally in LoginCommand:

private void writeField(OutputStream outputStream, String field) throws Exception {
    outputStream.write(field.getBytes());
    outputStream.write(0x00);
}

Replace all write/0x00 pairs in LoginCommand.write() with writeField(...) calls. Tests pass.

Step 4 — Replicate in AddEmployeeCmd: Same method, identical signature. Replace its pairs. Tests pass.

Step 5 — Introduce superclass: Create abstract Command class. Both classes extend it. Tests pass.

Step 6 — Pull up: Move writeField to Command. Delete local copies. Tests pass.

Step 8 — Emergence: After writeField is shared, both write() methods are structurally identical: header → size → commandChar → writeBody() → footer. Extract writeBody() as abstract. Pull write() to Command. Pull shared constants (header, footer, SIZE_LENGTH). The subclasses reduce to constructor + writeBody() + getCommandChar().

Final state: Command holds all protocol logic. Adding a new command is one subclass, no copy-paste.

Example 2: Two Validators with Repeated Null-Check Pattern

Situation: UserValidator and OrderValidator both open with:

if (input == null) {
    throw new IllegalArgumentException("input must not be null");
}

The guard is identical across both classes and three other validators as well.

Step 2 — Smallest fragment: The three-line null guard. Candidate name: requireNonNull(Object, String).

Steps 3–4: Extract to local method in UserValidator, replicate in OrderValidator. Tests pass in both.

Step 5: Check — do the validators share a parent? If they all extend a BaseValidator, pull up there. If not, decide: introduce AbstractValidator or extract to a shared utility class (ValidationUtils.requireNonNull). Choose based on whether validators truly share an identity or are only incidentally similar.

Step 8 — Observe: After the guard is shared, look at whether the remaining validation logic also shares structure. If all validators do: guard → validate fields → aggregate errors → return result, Template Method is emerging. Extract validateFields() as abstract and pull the outer structure up.

Example 3: Coincidental Similarity — Do NOT Extract

Situation: FilePermissionChecker and DatabaseConnectionPool each contain:

if (count < 0) {
    throw new IllegalArgumentException("count must be non-negative");
}

Analysis: FilePermissionChecker checks the number of retries. DatabaseConnectionPool checks the pool minimum size. These are semantically unrelated. The two classes have nothing in common — no shared parent makes sense, no shared utility class is appropriate.

Decision: do not extract. The similarity is coincidental. If the retry validation rule changes (e.g., to allow 0 retries), you would change FilePermissionChecker but not DatabaseConnectionPool. Coupling them would create false dependencies and make both harder to change.

The test: "If one copy needed to change, would the other need to change too?" Answer here: no. Leave them independent.

References

  • references/legacy-code-fundamentals.md — core definitions: legacy code, seams, characterization tests
  • references/refactoring-patterns.md — extract method, pull up method, template method mechanics

License

CC BY-SA 4.0 — BookForge Skills, derived from "Working Effectively with Legacy Code" by Michael C. Feathers. Skill interpretation, structure, and synthesis are original BookForge content.

Related BookForge Skills

Direct dependency (run before this skill):

  • characterization-test-writing — establish the regression safety net that makes each extraction step safe

Cross-references:

  • big-class-responsibility-extraction — when duplication removal reveals that a class is still doing too much, apply this next to split remaining responsibilities
  • dependency-breaking-technique-executor — the "Pull Up Feature" technique overlaps with pull-up mechanics; use when dependency breaking and duplication removal are both needed in the same class hierarchy

平台分布

OpenClaw

93.94%
按下载量换算977

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

调用外部服务

该 Skill 可能调用第三方服务、云服务或外部模型 API,使用前需要确认账号、额度、数据发送范围和服务条款。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills