mcpField
C
code-refactor-master

code-refactor-master

github.com/yennanliu开发14075 次安装今天更新
代码仓库

关于 code-refactor-master

面向希望改善代码结构且保持行为不变的开发者的重构 Skill,涵盖代码异味、常见重构、Java 与 Python 实践及渐进式测试流程。

主要功能

  1. 01识别常见代码异味
  2. 02应用方法与类级重构
  3. 03采用 Java 专属重构方式
  4. 04采用 Python 专属重构方式
  5. 05结合测试逐步重构
  6. 06在不改变行为时提升性能

适用场景

  1. 01减少重复代码与复杂度
  2. 02提升旧代码可维护性
  3. 03重构 Java 或 Python 解法
  4. 04优化算法实现

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yennanliu/cs_basics --skill code-refactor-master

安装后在 Claude Code 中输入/code-refactor-master确认已加载。

详细介绍

代码重构大师

何时使用此技能

在以下情况下使用此技能:

  • 重构现有代码,提升质量
  • 消除代码异味
  • 提高代码的可读性和可维护性
  • 在不改变行为的前提下优化性能
  • 应用设计模式
  • 降低复杂度
  • 清理技术债务

重构原则

1. 核心规则

黄金法则:改进代码的内部结构,但不改变外部行为

核心原则:

  • 一次只进行一项重构
  • 每次重构后运行测试
  • 频繁提交,并使用清晰的提交信息
  • 将重构与功能开发分开
  • 除非明确要更改 API,否则保持向后兼容

需要重构的警示信号:

  • 代码重复(DRY 原则)
  • 方法过长(>20-30 行)
  • 类过大(>300-500 行)
  • 参数列表过长(>3-4 个参数)
  • 条件语句嵌套过深(>3 层)
  • 注释在解释代码的作用(代码应能自我解释)
2. 常见代码异味

膨胀症:

  • 过长方法
  • 过大类
  • 基本类型偏执
  • 参数列表过长
  • 数据团块

面向对象滥用:

  • Switch 语句(考虑使用多态)
  • 临时字段
  • 拒绝继承
  • 接口不同的替代类

变更阻碍因素:

  • 发散式变化(一个类因多种原因而变更)
  • 散弹式修改(一次变更需要进行许多小改动)
  • 并行继承体系

可有可无的内容:

  • 注释(代码本应能自我解释的情况)
  • 重复代码
  • 懒惰类
  • 死代码
  • 推测性通用性

耦合症:

  • 特性嫉妒
  • 不恰当的亲密关系
  • 消息链
  • 中间人
3. 重构目录

方法级重构:

提取方法

// Before
void printOwing() {
    printBanner();
    // print details
    System.out.println("name: " + name);
    System.out.println("amount: " + getOutstanding());
}

// After
void printOwing() {
    printBanner();
    printDetails(getOutstanding());
}

void printDetails(double outstanding) {
    System.out.println("name: " + name);
    System.out.println("amount: " + outstanding);
}

内联方法

// Before - method too simple
int getRating() {
    return moreThanFiveLateDeliveries() ? 2 : 1;
}

boolean moreThanFiveLateDeliveries() {
    return numberOfLateDeliveries > 5;
}

// After
int getRating() {
    return numberOfLateDeliveries > 5 ? 2 : 1;
}

用查询替换临时变量

// Before
double calculateTotal() {
    double basePrice = quantity * itemPrice;
    if (basePrice > 1000) {
        return basePrice * 0.95;
    }
    return basePrice * 0.98;
}

// After
double calculateTotal() {
    if (basePrice() > 1000) {
        return basePrice() * 0.95;
    }
    return basePrice() * 0.98;
}

double basePrice() {
    return quantity * itemPrice;
}

变量级重构:

重命名变量

# Before
d = 10  # elapsed time in days

# After
elapsed_time_in_days = 10

拆分临时变量

// Before
double temp = 2 * (height + width);
System.out.println(temp);
temp = height * width;
System.out.println(temp);

// After
double perimeter = 2 * (height + width);
System.out.println(perimeter);
double area = height * width;
System.out.println(area);

类级重构:

提取类

// Before
class Person {
    String name;
    String officeAreaCode;
    String officeNumber;

    String getTelephoneNumber() {
        return "(" + officeAreaCode + ") " + officeNumber;
    }
}

// After
class Person {
    String name;
    TelephoneNumber officeTelephone = new TelephoneNumber();

    String getTelephoneNumber() {
        return officeTelephone.getTelephoneNumber();
    }
}

class TelephoneNumber {
    String areaCode;
    String number;

    String getTelephoneNumber() {
        return "(" + areaCode + ") " + number;
    }
}

以多态替换条件语句

# Before
class Bird:
    def get_speed(self):
        if self.type == "EUROPEAN":
            return self.get_base_speed()
        elif self.type == "AFRICAN":
            return self.get_base_speed() - self.get_load_factor()
        elif self.type == "NORWEGIAN_BLUE":
            return 0 if self.is_nailed else self.get_base_speed()

# After
class Bird:
    def get_speed(self):
        pass  # Abstract

class European(Bird):
    def get_speed(self):
        return self.get_base_speed()

class African(Bird):
    def get_speed(self):
        return self.get_base_speed() - self.get_load_factor()

class NorwegianBlue(Bird):
    def get_speed(self):
        return 0 if self.is_nailed else self.get_base_speed()
4. Java 专属重构

使用现代 Java 特性:

用 Lambda 替换匿名类

// Before
list.sort(new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

// After
list.sort((a, b) -> a.compareTo(b));
// Or even better
list.sort(String::compareTo);

使用 Streams API

// Before
List<String> result = new ArrayList<>();
for (String s : list) {
    if (s.length() > 3) {
        result.add(s.toUpperCase());
    }
}

// After
List<String> result = list.stream()
    .filter(s -> s.length() > 3)
    .map(String::toUpperCase)
    .collect(Collectors.toList());

替换字符串拼接

// Before - inefficient in loops
String result = "";
for (String s : list) {
    result += s + ", ";
}

// After
StringBuilder result = new StringBuilder();
for (String s : list) {
    result.append(s).append(", ");
}
// Or better
String result = String.join(", ", list);

使用 Optional

// Before
public User findUser(int id) {
    User user = database.getUser(id);
    return user != null ? user : new User();
}

// After
public Optional<User> findUser(int id) {
    return Optional.ofNullable(database.getUser(id));
}

用 Enum 替换类型码

// Before
public static final int TYPE_A = 1;
public static final int TYPE_B = 2;

// After
public enum Type {
    A, B
}
5. Python 专属重构

使用列表推导式

# Before
result = []
for item in items:
    if item > 0:
        result.append(item * 2)

# After
result = [item * 2 for item in items if item > 0]

使用 Collections 模块

# Before
counts = {}
for item in items:
    if item in counts:
        counts[item] += 1
    else:
        counts[item] = 1

# After
from collections import Counter
counts = Counter(items)

使用上下文管理器

# Before
file = open('file.txt')
data = file.read()
file.close()

# After
with open('file.txt') as file:
    data = file.read()

使用 f-string

# Before
message = "Hello, %s! You are %d years old." % (name, age)

# After
message = f"Hello, {name}! You are {age} years old."

使用类型提示

# Before
def process(data):
    return [x * 2 for x in data]

# After
def process(data: list[int]) -> list[int]:
    return [x * 2 for x in data]

使用 Dataclasses

# Before
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point(x={self.x}, y={self.y})"

# After
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int
6. 整洁代码原则

命名:

// Bad
int d; // elapsed time in days

// Good
int elapsedTimeInDays;

// Bad
public List<int[]> getThem() {
    List<int[]> list1 = new ArrayList<>();
    for (int[] x : theList) {
        if (x[0] == 4) {
            list1.add(x);
        }
    }
    return list1;
}

// Good
public List<Cell> getFlaggedCells() {
    List<Cell> flaggedCells = new ArrayList<>();
    for (Cell cell : gameBoard) {
        if (cell.isFlagged()) {
            flaggedCells.add(cell);
        }
    }
    return flaggedCells;
}

函数:

  • 短小(最多 20-30 行)
  • 只做一件事
  • 只处于一个抽象层级
  • 使用描述性名称
  • 参数尽量少(理想情况下为 0-3 个)

注释:

// Bad - comment explains what code does
// Check to see if employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))

// Good - code is self-explanatory
if (employee.isEligibleForFullBenefits())
7. 性能重构

算法优化:

# Before - O(n²)
def has_duplicates(arr):
    for i in range(len(arr)):
        for j in range(i + 1, len(arr)):
            if arr[i] == arr[j]:
                return True
    return False

# After - O(n)
def has_duplicates(arr):
    return len(arr) != len(set(arr))

惰性求值:

// Before - computes all values
List<Integer> results = list.stream()
    .map(this::expensiveOperation)
    .collect(Collectors.toList());
return results.get(0);

// After - computes only what's needed
return list.stream()
    .map(this::expensiveOperation)
    .findFirst()
    .orElse(null);

记忆化:

# Before
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

# After
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
8. 重构工作流

逐步流程:

  1. 识别:找到代码异味或改进机会
  2. 规划:决定要应用哪种重构
  3. 测试:确保测试已编写且通过
  4. 重构:进行一项小改动
  5. 测试:再次运行测试
  6. 提交:保存可正常工作的状态
  7. 重复:继续进行下一项重构

工作流示例:

# 1. Create feature branch
git checkout -b refactor/improve-user-service

# 2. Identify issue (e.g., long method)
# Read code, find UserService.processUser() is 150 lines

# 3. Run existing tests
mvn test  # or pytest

# 4. Extract method
# Break processUser into smaller methods

# 5. Run tests
mvn test  # Ensure still passing

# 6. Commit
git commit -m "refactor: extract validateUser method"

# 7. Continue
# Extract next method, repeat
9. 重构检查清单

重构前:

  • 测试已编写且通过
  • 理解代码行为
  • 有明确的目标
  • 知道要应用哪种重构

重构过程中:

  • 进行小幅、渐进式改动
  • 每次改动后运行测试
  • 始终确保代码可正常工作
  • 频繁提交

重构后:

  • 所有测试均通过
  • 代码更易读
  • 复杂度降低
  • 行为未发生变化
  • 如有需要,更新文档
10. LeetCode 专属重构

优化暴力解法:

// Before - Brute force O(n²)
public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[i] + nums[j] == target) {
                return new int[]{i, j};
            }
        }
    }
    return new int[]{};
}

// After - Hash map O(n)
public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement)) {
            return new int[]{map.get(complement), i};
        }
        map.put(nums[i], i);
    }
    return new int[]{};
}

提取辅助方法:

# Before - monolithic
def solve(self, grid):
    # 50 lines of code mixing concerns

# After - modular
def solve(self, grid):
    if not self.is_valid(grid):
        return []

    processed = self.preprocess(grid)
    result = self.compute(processed)
    return self.format_output(result)

def is_valid(self, grid):
    # validation logic

def preprocess(self, grid):
    # preprocessing logic

def compute(self, data):
    # core algorithm

def format_output(self, result):
    # formatting logic

重构反模式

不要:

  • 在没有测试的情况下重构
  • 在重构期间改变行为
  • 一次进行多项更改
  • 同时重构和添加功能
  • 对简单代码过度设计
  • 过早优化

项目背景

对于 CS_basics 仓库:

  • 重构 leetcode_java/ 和 leetcode_python/ 中的解法
  • 保持不同语言实现之间的一致性
  • 更新算法说明
  • 遵循项目规范
  • 使用示例输入测试重构后的代码
  • 记录复杂度改进

工具和资源

IDE 重构工具:

  • IntelliJ IDEA:重构菜单(Ctrl+Alt+Shift+T)
  • VS Code:Python 重构扩展
  • PyCharm:重构操作

在可用时使用自动重构:

  • 重命名:安全地在整个项目中重命名
  • 提取方法/变量:自动提取
  • 内联:预览后安全地内联
  • 移动:重组包/模块

评论

支持 Markdown