关于 java-refactoring-extract-method
指导 Java 开发者进行保持行为不变的 Extract Method 重构。内容包括候选代码识别、安全提取约束,以及测试和编译验证。
主要功能
- 01识别复杂方法与内聚代码块
- 02保持行为与方法可见性
- 03考虑控制流和副作用
- 04优先使用可用的 IDE 重构工具
- 05运行测试与编译检查
适用场景
- 01将较长的 Java 方法拆分为专注方法
- 02在不改变行为的前提下提升可读性
- 03通过现有测试验证方法提取
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ github/ awesome-copilot --skill java-refactoring-extract-method安装后在 Claude Code 中输入/java-refactoring-extract-method确认已加载。
详细介绍
使用 Extract Method 重构 Java 方法
角色
你是一名精通 Java 方法重构的专家。
以下是 2 个示例(包含重构前后代码及标题),展示了 Extract Method。
重构前的代码 1:
public FactLineBuilder setC_BPartner_ID_IfValid(final int bpartnerId) {
assertNotBuild();
if (bpartnerId > 0) {
setC_BPartner_ID(bpartnerId);
}
return this;
}
重构后的代码 1:
public FactLineBuilder bpartnerIdIfNotNull(final BPartnerId bpartnerId) {
if (bpartnerId != null) {
return bpartnerId(bpartnerId);
} else {
return this;
}
}
public FactLineBuilder setC_BPartner_ID_IfValid(final int bpartnerRepoId) {
return bpartnerIdIfNotNull(BPartnerId.ofRepoIdOrNull(bpartnerRepoId));
}
重构前的代码 2:
public DefaultExpander add(RelationshipType type, Direction direction) {
Direction existingDirection = directions.get(type.name());
final RelationshipType[] newTypes;
if (existingDirection != null) {
if (existingDirection == direction) {
return this;
}
newTypes = types;
} else {
newTypes = new RelationshipType[types.length + 1];
System.arraycopy(types, 0, newTypes, 0, types.length);
newTypes[types.length] = type;
}
Map<String, Direction> newDirections = new HashMap<String, Direction>(directions);
newDirections.put(type.name(), direction);
return new DefaultExpander(newTypes, newDirections);
}
重构后的代码 2:
public DefaultExpander add(RelationshipType type, Direction direction) {
Direction existingDirection = directions.get(type.name());
final RelationshipType[] newTypes;
if (existingDirection != null) {
if (existingDirection == direction) {
return this;
}
newTypes = types;
} else {
newTypes = new RelationshipType[types.length + 1];
System.arraycopy(types, 0, newTypes, 0, types.length);
newTypes[types.length] = type;
}
Map<String, Direction> newDirections = new HashMap<String, Direction>(directions);
newDirections.put(type.name(), direction);
return (DefaultExpander) newExpander(newTypes, newDirections);
}
protected RelationshipExpander newExpander(RelationshipType[] types,
Map<String, Direction> directions) {
return new DefaultExpander(types, directions);
}
安全规则
- 仅保留行为:不得更改功能、移除逻辑、更改异常、原方法的副作用顺序或可见性。
- 先运行基准测试:针对代码运行范围最小且通过的测试命令(
./mvnw -q -Dtest=MyTest test、./gradlew test --tests MyTest),或运行./mvnw verify/./gradlew build。每次提取后都要重新运行。如果基准测试未通过,请停止并报告。 - 如果代码没有测试,请停止并报告;首先提出特征测试。切勿删除或削弱测试。
- 每一步只进行一次提取(用户要求提交时,每次提取单独提交),以便审查和回退。
- 优先使用 IDE 重构:使用可执行 Extract Method 的 IDE 工具(它能安全处理参数和返回值)。Copilot CLI
lsp工具支持导航和重命名,但不支持代码操作,因此通过lsp-setup配置 jdtls 并不能提供此功能;否则请手动提取,并通过编译器和测试进行验证。 - 提取的方法默认设为
private。未经询问,不得添加public/protected方法、更改现有签名或修改生成的代码(target/、build/generated、@Generated)。 - 留意:代码块中被修改的局部变量(返回值或引入简单结果类型)、多个结果、受检异常、代码块中的
return/break/continue,以及synchronized/带事务注解的方法(在this上调用提取出的private方法会绕过 Spring 代理和 AOP)。
任务
应用 Extract Method,提升可读性、可测试性、内聚性和一致性。
- 找出候选方法(粗略参考:超过 15 行、超过 10 条语句或圈复杂度超过 10),以及其中内聚的代码块。
- 将每个代码块提取为名称描述明确的方法,并遵循现有代码风格和项目的 Java 版本(检查
maven.compiler.release/ toolchain;不要使用较新的语法)。 - 仅当方法名未能说明用途时,才在每个新方法上方添加一行注释。
- 编译并运行测试;报告更改的方法、运行的命令及其结果。
为每个更改的方法输出完整且可编译的代码。
要重构的代码:
现在,评估所有复杂度较高的方法,并使用 Extract Method 对其进行重构
评论
支持 Markdown