mcpField
J
java-refactoring-extract-method

java-refactoring-extract-method

github.com/github开发40.5k9.3k 次安装1 天前更新
代码仓库

关于 java-refactoring-extract-method

指导 Java 开发者进行保持行为不变的 Extract Method 重构。内容包括候选代码识别、安全提取约束,以及测试和编译验证。

主要功能

  1. 01识别复杂方法与内聚代码块
  2. 02保持行为与方法可见性
  3. 03考虑控制流和副作用
  4. 04优先使用可用的 IDE 重构工具
  5. 05运行测试与编译检查

适用场景

  1. 01将较长的 Java 方法拆分为专注方法
  2. 02在不改变行为的前提下提升可读性
  3. 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,提升可读性、可测试性、内聚性和一致性。

  1. 找出候选方法(粗略参考:超过 15 行、超过 10 条语句或圈复杂度超过 10),以及其中内聚的代码块。
  2. 将每个代码块提取为名称描述明确的方法,并遵循现有代码风格和项目的 Java 版本(检查 maven.compiler.release / toolchain;不要使用较新的语法)。
  3. 仅当方法名未能说明用途时,才在每个新方法上方添加一行注释。
  4. 编译并运行测试;报告更改的方法、运行的命令及其结果。

为每个更改的方法输出完整且可编译的代码。

要重构的代码:

现在,评估所有复杂度较高的方法,并使用 Extract Method 对其进行重构

评论

支持 Markdown