代码重构助手
SkillMediaCode refactoring assistant based on Refactoring: Improving the Design of Existing Code (2nd Edition). Includes 28 code smell identification methods and all 61 refactoring techniques. Use cases: (1) identify code smells and get refactoring suggestions, (2) look up detailed steps and examples for a sp
Use 代码重构助手 in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add 代码重构助手 and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the 代码重构助手 skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by onweekendd/screenwright in .claude/skills/refactoring/SKILL.md and read by Ahel’s review.
本 skill 基于 Martin Fowler 的《重构:改善既有代码的设计(第2版)》,提供代码坏味道识别和系统化的重构指导。
快速开始
识别代码坏味道
当发现代码问题时,可对照以下28种坏味道进行识别(基于《重构》第2版 24种核心坏味道 + 4种常见变体):
| 坏味道 | 典型特征 | 推荐重构 |
|---|---|---|
| 神秘的命名 | 名字不能清晰表达用途 | 变量改名(137)、函数改名(124)、字段改名(244) |
| 重复代码 | 相同代码结构出现在多处 | 提炼函数(106)、提炼类(182)、函数上移(350)、字段上移(353)、滑动语句(223) |
| 过长函数 | 函数体超过一屏或包含多层抽象 | 提炼函数(106)、拆分阶段(155)、以命令取代函数(337)、以查询取代临时变量(178) |
| 过长参数列表 | 参数超过3-4个 | 引入参数对象(140)、保持对象完整(319)、以查询取代参数(324) |
| 全局数据 | 任何地方都可访问和修改 | 封装变量(132)、封装记录(162) |
| 可变数据 | 数据在多处被修改 | 封装变量(132)、以查询取代派生变量(248)、移除设值函数(331)、拆分变量(240)、将引用对象改为值对象(252) |
| 发散式变化 | 一个类因多种原因修改 | 提炼类(182)、提炼超类(375)、拆分阶段(155) |
| 霰弹式修改 | 每次修改需改动多个类 | 搬移函数(198)、搬移字段(201)、以函数调用取代内联代码(217)、组合函数为类(144)、组合函数为变换(149) |
| 依恋情结 | 函数更多使用其他类数据 | 搬移函数(198)、搬移字段(201)、提炼函数(106) |
| 数据泥团 | 总是同时出现的一组数据 | 引入参数对象(140)、提炼类(182)、保持对象完整(319) |
| 基本类型偏执 | 过度使用基本类型 | 以对象取代基本类型(174)、封装记录(162)、将值对象改为引用对象(256) |
| 重复的switch | 相同switch逻辑多处出现 | 以多态取代条件表达式(272)、以子类取代类型码(362) |
| 循环 | 使用传统循环而非管道 | 以管道取代循环(231)、拆分循环(227) |
| 冗赘的元素 | 不再使用的代码(未用函数/类/接口) | 移除死代码(237)、内联函数(115)、内联类(186)、折叠继承体系(380)、移除子类(369) |
| 夸夸其谈通用性 | 为未存在需求设计的抽象(过度设计) | 折叠继承体系(380)、移除子类(369)、以委托取代超类(399)、内联函数(115)、内联类(186) |
| 临时字段 | 字段只在特定情况使用 | 提炼类(182)、引入特例(289) |
| 过长的消息链 | a.b.c.d 调用链 | 隐藏委托关系(189)、提炼函数(106)、搬移函数(198) |
| 中间人 | 类大部分函数委托给其他类 | 移除中间人(192)、内联类(186) |
| 过大的类 | 类承担过多责任 | 提炼类(182)、拆分阶段(155)、提炼超类(375)、提炼子类(以子类取代类型码362) |
| 异曲同工的类 | 不同类做同样事但接口不同 | 改变函数声明(124)、搬移函数(198)、提炼超类(375) |
| 数据类 | 只有数据没有行为 | 封装记录(162)、封装集合(170)、移除设值函数(331)、搬移函数(198) |
| 被拒绝的遗赠 | 子类不需要超类部分功能 | 以委托取代子类(381)、函数下移(359)、字段下移(361)、以委托取代超类(399) |
| 注释 | 用注释解释"做什么"而非"为什么" | 提炼函数(106)、改变函数声明(124)、引入断言(302) |
| 不恰当的亲密 | 类之间过度了解彼此内部(直接访问私有成员) | 搬移函数(198)、搬移字段(201)、隐藏委托关系(189)、提炼类(182) |
| 内幕交易 | 类之间通过其他类间接访问(过度耦合) | 搬移函数(198)、搬移字段(201)、隐藏委托关系(189)、以委托取代超类(399)、以委托取代子类(381) |
| 令人迷惑的临时变量 | 变量用途不清晰或多次赋值 | 拆分变量(240)、变量改名(137)、提炼变量(119)、内联变量(123)、以查询取代临时变量(178) |
| 不必要的上下文 | 函数接收完整对象但只用部分字段 | 以查询取代参数(324)、保持对象完整(319反向)、搬移函数(198) |
| 发散的递归/嵌套 | 深度嵌套的条件或递归难以跟踪 | 以卫语句取代嵌套条件(266)、分解条件表达式(260)、引入特例(289) |
| 死代码 | 永远不会执行的代码分支 | 移除死代码(237)、折叠继承体系(380)、移除子类(369) |
| 交叉赋值 | 变量承担多个职责 | 拆分变量(240)、以查询取代派生变量(248) |
重构手法分组
根据代码问题类型,选择对应章节的详细参考:
- 基础重构 → ch6-first-group.md
- 封装相关 → ch7-encapsulation.md
- 搬移特性 → ch8-moving-features.md
- 数据组织 → ch9-reorganizing-data.md
- 条件逻辑 → ch10-simplifying-conditionals.md
- API重构 → ch11-refactoring-apis.md
- 继承关系 → ch12-handling-inheritance.md
重构原则
两顶帽子
使用重构时,要明确自己当前戴的是哪顶帽子:
- 添加功能:添加新能力,不修改已有代码
- 重构:调整代码结构,不添加新功能
不要同时戴上这两顶帽子。
重构的定义
重构是对软件内部结构的一种调整,目的是在不改变软件可观察行为的前提下,提高其可理解性、降低其修改成本。
何时重构
- 事不过三:同样的代码出现第三次时,进行重构
- 添加功能时:如果代码结构妨碍添加功能,先重构
- 修复bug时:如果代码难以理解,先重构
- 代码审查时:发现需要改进的地方
何时不重构
- 需要完全重写时
- 项目临近截止时
- 代码不会被使用时
常用重构速查
| 编号 | 名称 | 用途 |
|---|---|---|
| 基础重构 (Chapter 6) | ||
| 106 | 提炼函数 (Extract Function) | 将一段代码提取为独立函数 |
| 115 | 内联函数 (Inline Function) | 将函数调用替换为函数体 |
| 119 | 提炼变量 (Extract Variable) | 将表达式提取为变量 |
| 123 | 内联变量 (Inline Variable) | 将变量替换为表达式 |
| 124 | 改变函数声明 (Change Function Declaration) | 修改函数名或参数列表 |
| 132 | 封装变量 (Encapsulate Variable) | 通过函数访问变量,限制直接修改 |
| 137 | 变量改名 (Rename Variable) | 给变量更好的名字 |
| 封装相关 (Chapter 7) | ||
| 140 | 引入参数对象 (Introduce Parameter Object) | 将多个相关参数组合成对象 |
| 144 | 组合函数为类 (Combine Functions into Class) | 将相关函数和数据组织成类 |
| 149 | 组合函数为变换 (Combine Functions into Transform) | 用变换函数组织计算逻辑,返回深拷贝 |
| 155 | 拆分阶段 (Split Phase) | 将代码分为独立处理阶段,中间用数据结构传递 |
| 162 | 封装记录 (Encapsulate Record) | 给记录结构添加封装行为 |
| 170 | 封装集合 (Encapsulate Collection) | 控制集合的访问方式,避免外部直接修改 |
| 174 | 以对象取代基本类型 (Replace Primitive with Object) | 将基本类型转为富对象 |
| 178 | 以查询取代临时变量 (Replace Temp with Query) | 将临时变量转为查询函数 |
| 182 | 提炼类 (Extract Class) | 将类的部分职责提取到新类 |
| 186 | 内联类 (Inline Class) | 将一个类合并到另一个类 |
| 189 | 隐藏委托关系 (Hide Delegate) | 隐藏对象间的委托关系,减少耦合 |
| 192 | 移除中间人 (Remove Middle Man) | 让客户端直接访问受托对象 |
| 195 | 替换算法 (Substitute Algorithm) | 用更清晰的算法替换旧算法 |
| 搬移特性 (Chapter 8) | ||
| 198 | 搬移函数 (Move Function) | 将函数移到更合适的类 |
| 201 | 搬移字段 (Move Field) | 将字段移到更合适的类 |
| 207 | 搬移语句到函数 (Move Statements into Function) | 将调用者重复代码移到函数内 |
| 213 | 搬移语句到调用者 (Move Statements to Callers) | 将函数内特定代码移到调用者 |
| 217 | 以函数调用取代内联代码 (Replace Inline Code with Function Call) | 用语言内置或库函数替换重复代码 |
| 223 | 滑动语句 (Slide Statements) | 调整代码顺序,让相关代码聚集 |
| 227 | 拆分循环 (Split Loop) | 将一个循环拆分为多个,每个只做一件事 |
| 231 | 以管道取代循环 (Replace Loop with Pipeline) | 用map/filter/reduce等管道操作替换循环 |
| 237 | 移除死代码 (Remove Dead Code) | 删除不再使用的代码 |
| 数据组织 (Chapter 9) | ||
| 240 | 拆分变量 (Split Variable) | 将一个被多次赋值的变量分解为多个 |
| 244 | 字段改名 (Rename Field) | 给字段更好的名字 |
| 248 | 以查询取代派生变量 (Replace Derived Variable with Query) | 用计算代替存储,消除数据同步问题 |
| 252 | 将引用对象改为值对象 (Change Reference to Value) | 让对象不可变,便于理解和测试 |
| 256 | 将值对象改为引用对象 (Change Value to Reference) | 共享对象,确保数据一致性 |
| 条件逻辑 (Chapter 10) | ||
| 260 | 分解条件表达式 (Decompose Conditional) | 将复杂条件提取为有意义的函数 |
| 263 | 合并条件表达式 (Consolidate Conditional Expression) | 合并结果相同的多个条件 |
| 266 | 以卫语句取代嵌套条件表达式 (Replace Nested Conditional with Guard Clauses) | 用卫语句简化深层嵌套 |
| 272 | 以多态取代条件表达式 (Replace Conditional with Polymorphism) | 用多态替换复杂的条件逻辑 |
| 289 | 引入特例 (Introduce Special Case) | 用特例类处理null/默认值情况 |
| 302 | 引入断言 (Introduce Assertion) | 明确表述程序状态的假设 |
| API重构 (Chapter 11) | ||
| 306 | 将查询函数和修改函数分离 (Separate Query from Modifier) | 分离命令和查询(CQS原则) |
| 310 | 函数参数化 (Parameterize Function) | 用参数统一相似的函数 |
| 314 | 移除标记参数 (Remove Flag Argument) | 用独立函数替换布尔/标记参数 |
| 319 | 保持对象完整 (Preserve Whole Object) | 传递整个对象而非拆解的字段 |
| 324 | 以查询取代参数 (Replace Parameter with Query) | 函数内部可获取的值不再作为参数 |
| 327 | 以参数取代查询 (Replace Query with Parameter) | 用参数替换内部查询,减少依赖 |
| 331 | 移除设值函数 (Remove Setting Method) | 使字段不可变,只能在构造函数设置 |
| 334 | 以工厂函数取代构造函数 (Replace Constructor with Factory Function) | 用描述性工厂函数创建对象 |
| 337 | 以命令取代函数 (Replace Function with Command) | 将复杂函数转为命令对象 |
| 344 | 以函数取代命令 (Replace Command with Function) | 将简单命令对象转回函数 |
| 继承关系 (Chapter 12) | ||
| 350 | 函数上移 (Pull Up Method) | 将子类相同函数移到超类 |
| 353 | 字段上移 (Pull Up Field) | 将子类相同字段移到超类 |
| 355 | 构造函数本体上移 (Pull Up Constructor Body) | 将子类构造函数共同逻辑移到超类 |
| 359 | 函数下移 (Push Down Method) | 将超类特定函数移到子类 |
| 361 | 字段下移 (Push Down Field) | 将超类特定字段移到子类 |
| 362 | 以子类取代类型码 (Replace Type Code with Subclasses) | 用继承替换类型码 |
| 369 | 移除子类 (Remove Subclass) | 用字段替换简单的子类 |
| 375 | 提炼超类 (Extract Superclass) | 将共同部分提取为超类 |
| 380 | 折叠继承体系 (Collapse Hierarchy) | 合并不再需要的继承层次 |
| 381 | 以委托取代子类 (Replace Subclass with Delegate) | 用委托替换继承(组合优于继承) |
| 399 | 以委托取代超类 (Replace Superclass with Delegate) | 用委托替换超类继承 |
Signals
- GitHub stars
- 30
- Last commit
- Sep 2026
Advanced
- Item type
- skill
- Key
refactoring-onweekendd- Source
- github.com/onweekendd/screenwright
github.com/onweekendd/screenwright