code-refactor-master

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Refactor Master

代码重构大师

When to use this Skill

何时使用该Skill

Use this Skill when:
  • Refactoring existing code for better quality
  • Eliminating code smells
  • Improving code readability and maintainability
  • Optimizing performance without changing behavior
  • Applying design patterns
  • Reducing complexity
  • Cleaning up technical debt
使用该Skill的场景:
  • 为提升代码质量重构现有代码
  • 消除代码坏味
  • 提升代码可读性与可维护性
  • 在不改变行为的前提下优化性能
  • 应用设计模式
  • 降低复杂度
  • 清理技术债务

Refactoring Principles

重构原则

1. Core Rules

1. 核心准则

Golden Rule: Make code changes that improve internal structure without altering external behavior
Key Principles:
  • One refactoring at a time
  • Run tests after each refactoring
  • Commit frequently with clear messages
  • Keep refactoring separate from feature work
  • Maintain backwards compatibility unless explicitly changing API
Red Flags to Refactor:
  • Code duplication (DRY principle)
  • Long methods (>20-30 lines)
  • Large classes (>300-500 lines)
  • Long parameter lists (>3-4 parameters)
  • Deeply nested conditionals (>3 levels)
  • Comments explaining what code does (code should be self-explanatory)
黄金准则:修改代码以优化内部结构,但不改变外部行为
关键原则:
  • 一次只进行一项重构
  • 每次重构后运行测试
  • 频繁提交,且提交信息清晰明确
  • 重构与功能开发分开进行
  • 除非明确修改API,否则保持向后兼容性
需要重构的预警信号:
  • 代码重复(遵循DRY原则)
  • 过长方法(超过20-30行)
  • 过大类(超过300-500行)
  • 过长参数列表(超过3-4个参数)
  • 过深嵌套条件(超过3层)
  • 存在解释代码功能的注释(代码应具备自解释性)

2. Common Code Smells

2. 常见代码坏味

Bloaters:
  • Long Method
  • Large Class
  • Primitive Obsession
  • Long Parameter List
  • Data Clumps
Object-Orientation Abusers:
  • Switch Statements (consider polymorphism)
  • Temporary Field
  • Refused Bequest
  • Alternative Classes with Different Interfaces
Change Preventers:
  • Divergent Change (one class changes for many reasons)
  • Shotgun Surgery (one change requires many small changes)
  • Parallel Inheritance Hierarchies
Dispensables:
  • Comments (where code should be self-explanatory)
  • Duplicate Code
  • Lazy Class
  • Dead Code
  • Speculative Generality
Couplers:
  • Feature Envy
  • Inappropriate Intimacy
  • Message Chains
  • Middle Man
臃肿型坏味:
  • Long Method
  • Large Class
  • Primitive Obsession
  • Long Parameter List
  • Data Clumps
面向对象滥用型坏味:
  • Switch Statements (consider polymorphism)
  • Temporary Field
  • Refused Bequest
  • Alternative Classes with Different Interfaces
变更阻碍型坏味:
  • Divergent Change (one class changes for many reasons)
  • Shotgun Surgery (one change requires many small changes)
  • Parallel Inheritance Hierarchies
冗余型坏味:
  • Comments (where code should be self-explanatory)
  • Duplicate Code
  • Lazy Class
  • Dead Code
  • Speculative Generality
耦合型坏味:
  • Feature Envy
  • Inappropriate Intimacy
  • Message Chains
  • Middle Man

3. Refactoring Catalog

3. 重构目录

Method-Level Refactorings:
Extract Method
java
// 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);
}
Inline Method
java
// Before - method too simple
int getRating() {
    return moreThanFiveLateDeliveries() ? 2 : 1;
}

boolean moreThanFiveLateDeliveries() {
    return numberOfLateDeliveries > 5;
}

// After
int getRating() {
    return numberOfLateDeliveries > 5 ? 2 : 1;
}
Replace Temp with Query
java
// 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;
}
Variable-Level Refactorings:
Rename Variable
python
undefined
方法级重构:
Extract Method
java
// 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);
}
Inline Method
java
// Before - method too simple
int getRating() {
    return moreThanFiveLateDeliveries() ? 2 : 1;
}

boolean moreThanFiveLateDeliveries() {
    return numberOfLateDeliveries > 5;
}

// After
int getRating() {
    return numberOfLateDeliveries > 5 ? 2 : 1;
}
Replace Temp with Query
java
// 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;
}
变量级重构:
Rename Variable
python
undefined

Before

Before

d = 10 # elapsed time in days
d = 10 # elapsed time in days

After

After

elapsed_time_in_days = 10

**Split Temporary Variable**
```java
// 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);
Class-Level Refactorings:
Extract Class
java
// 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;
    }
}
Replace Conditional with Polymorphism
python
undefined
elapsed_time_in_days = 10

**Split Temporary Variable**
```java
// 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);
类级重构:
Extract Class
java
// 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;
    }
}
Replace Conditional with Polymorphism
python
undefined

Before

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()
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

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()
undefined
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()
undefined

4. Java-Specific Refactorings

4. Java专属重构技巧

Use Modern Java Features:
Replace Anonymous Class with Lambda
java
// 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);
Use Streams API
java
// 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());
Replace String Concatenation
java
// 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);
Use Optional
java
// 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));
}
Replace Type Code with Enum
java
// Before
public static final int TYPE_A = 1;
public static final int TYPE_B = 2;

// After
public enum Type {
    A, B
}
使用现代Java特性:
Replace Anonymous Class with Lambda
java
// 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);
Use Streams API
java
// 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());
Replace String Concatenation
java
// 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);
Use Optional
java
// 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));
}
Replace Type Code with Enum
java
// Before
public static final int TYPE_A = 1;
public static final int TYPE_B = 2;

// After
public enum Type {
    A, B
}

5. Python-Specific Refactorings

5. Python专属重构技巧

Use List Comprehensions
python
undefined
Use List Comprehensions
python
undefined

Before

Before

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

After

After

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

**Use Collections Module**
```python
result = [item * 2 for item in items if item > 0]

**Use Collections Module**
```python

Before

Before

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

After

After

from collections import Counter counts = Counter(items)

**Use Context Managers**
```python
from collections import Counter counts = Counter(items)

**Use Context Managers**
```python

Before

Before

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

After

After

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

**Use f-strings**
```python
with open('file.txt') as file: data = file.read()

**Use f-strings**
```python

Before

Before

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

After

After

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

**Use Type Hints**
```python
message = f"Hello, {name}! You are {age} years old."

**Use Type Hints**
```python

Before

Before

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

After

After

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

**Use Dataclasses**
```python
def process(data: list[int]) -> list[int]: return [x * 2 for x in data]

**Use Dataclasses**
```python

Before

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})"
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

After

from dataclasses import dataclass
@dataclass class Point: x: int y: int
undefined
from dataclasses import dataclass
@dataclass class Point: x: int y: int
undefined

6. Clean Code Principles

6. 清洁代码原则

Naming:
java
// 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;
}
Functions:
  • Small (20-30 lines max)
  • Do one thing
  • One level of abstraction
  • Descriptive names
  • Few arguments (0-3 ideal)
Comments:
java
// 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())
命名规范:
java
// 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个为最佳)
注释规范:
java
// 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. Performance Refactorings

7. 性能优化重构

Algorithm Optimization:
python
undefined
算法优化:
python
undefined

Before - O(n²)

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
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)

After - O(n)

def has_duplicates(arr): return len(arr) != len(set(arr))

**Lazy Evaluation:**
```java
// 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);
Memoization:
python
undefined
def has_duplicates(arr): return len(arr) != len(set(arr))

**延迟计算:**
```java
// 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);
记忆化:
python
undefined

Before

Before

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

After

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)
undefined
from functools import lru_cache
@lru_cache(maxsize=None) def fibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2)
undefined

8. Refactoring Workflow

8. 重构工作流程

Step-by-step process:
  1. Identify: Find code smell or improvement opportunity
  2. Plan: Decide which refactoring to apply
  3. Test: Ensure tests exist and pass
  4. Refactor: Make one small change
  5. Test: Run tests again
  6. Commit: Save working state
  7. Repeat: Continue with next refactoring
Example workflow:
bash
undefined
分步流程:
  1. 识别:找出代码坏味或优化机会
  2. 规划:确定要应用的重构方式
  3. 测试:确保测试用例存在且全部通过
  4. 重构:进行微小的修改
  5. 测试:再次运行测试
  6. 提交:保存当前工作状态
  7. 重复:继续下一项重构
工作流示例:
bash
undefined

1. Create feature branch

1. Create feature branch

git checkout -b refactor/improve-user-service
git checkout -b refactor/improve-user-service

2. Identify issue (e.g., long method)

2. Identify issue (e.g., long method)

Read code, find UserService.processUser() is 150 lines

Read code, find UserService.processUser() is 150 lines

3. Run existing tests

3. Run existing tests

mvn test # or pytest
mvn test # or pytest

4. Extract method

4. Extract method

Break processUser into smaller methods

Break processUser into smaller methods

5. Run tests

5. Run tests

mvn test # Ensure still passing
mvn test # Ensure still passing

6. Commit

6. Commit

git commit -m "refactor: extract validateUser method"
git commit -m "refactor: extract validateUser method"

7. Continue

7. Continue

Extract next method, repeat

Extract next method, repeat

undefined
undefined

9. Refactoring Checklist

9. 重构检查清单

Before refactoring:
  • Tests exist and pass
  • Understand the code behavior
  • Have a clear goal
  • Know which refactoring to apply
During refactoring:
  • Make small, incremental changes
  • Run tests after each change
  • Keep code working at all times
  • Commit frequently
After refactoring:
  • All tests pass
  • Code is more readable
  • Complexity reduced
  • No behavioral changes
  • Documentation updated if needed
重构前:
  • 测试用例存在且全部通过
  • 理解代码行为
  • 明确重构目标
  • 确定要应用的重构方式
重构中:
  • 进行微小、渐进的修改
  • 每次修改后运行测试
  • 确保代码始终可正常运行
  • 频繁提交
重构后:
  • 所有测试用例通过
  • 代码可读性提升
  • 复杂度降低
  • 代码行为未发生改变
  • 必要时更新文档

10. LeetCode-Specific Refactoring

10. LeetCode专属重构技巧

Optimize brute force:
java
// 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[]{};
}
Extract helper methods:
python
undefined
优化暴力解法:
java
// 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[]{};
}
提取辅助方法:
python
undefined

Before - monolithic

Before - monolithic

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

After - modular

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
undefined
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
undefined

Refactoring Anti-Patterns

重构反模式

Don't:
  • Refactor without tests
  • Change behavior during refactoring
  • Make multiple changes at once
  • Refactor and add features simultaneously
  • Over-engineer simple code
  • Prematurely optimize
请勿:
  • 在无测试用例的情况下进行重构
  • 重构过程中修改代码行为
  • 同时进行多项修改
  • 同时进行重构与功能新增
  • 对简单代码过度设计
  • 过早进行性能优化

Project Context

项目上下文

For CS_basics repository:
  • Refactor solutions in
    leetcode_java/
    and
    leetcode_python/
  • Maintain consistency across language implementations
  • Keep algorithm explanations updated
  • Follow project conventions
  • Test refactored code with example inputs
  • Document complexity improvements
针对CS_basics仓库:
  • 重构
    leetcode_java/
    leetcode_python/
    目录下的解决方案
  • 保持不同语言实现的一致性
  • 及时更新算法说明
  • 遵循项目规范
  • 使用示例输入测试重构后的代码
  • 记录复杂度优化情况

Tools and Resources

工具与资源

IDE Refactoring Tools:
  • IntelliJ IDEA: Refactor menu (Ctrl+Alt+Shift+T)
  • VS Code: Python refactoring extensions
  • PyCharm: Refactoring actions
Use automated refactoring when available:
  • Rename: Safe renaming across project
  • Extract method/variable: Automatic extraction
  • Inline: Safe inlining with preview
  • Move: Restructure packages/modules
IDE重构工具:
  • IntelliJ IDEA:重构菜单(快捷键Ctrl+Alt+Shift+T)
  • VS Code:Python重构扩展
  • PyCharm:重构操作
尽可能使用自动化重构:
  • 重命名:跨项目安全重命名
  • 提取方法/变量:自动提取
  • 内联:带预览的安全内联
  • 移动:重构包/模块结构