| name | code-refactor-master |
| description | Code refactoring expert for improving code quality, readability, maintainability, and performance. Specializes in Java and Python refactoring patterns, eliminating code smells, and applying clean code principles. Use when refactoring code, improving existing implementations, or cleaning up technical debt. |
| allowed-tools | Read, Glob, Grep, Edit, LSP |
Code Refactor Master
When to use this 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
Refactoring Principles
1. Core Rules
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)
2. Common Code Smells
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
3. Refactoring Catalog
Method-Level Refactorings:
Extract Method
void printOwing() {
printBanner();
System.out.println("name: " + name);
System.out.println("amount: " + getOutstanding());
}
void printOwing() {
printBanner();
printDetails(getOutstanding());
}
void printDetails(double outstanding) {
System.out.println("name: " + name);
System.out.println("amount: " + outstanding);
}
Inline Method
int getRating() {
return moreThanFiveLateDeliveries() ? 2 : 1;
}
boolean moreThanFiveLateDeliveries() {
return numberOfLateDeliveries > 5;
}
int getRating() {
return numberOfLateDeliveries > 5 ? 2 : 1;
}
Replace Temp with Query
double calculateTotal() {
double basePrice = quantity * itemPrice;
if (basePrice > 1000) {
return basePrice * 0.95;
}
return basePrice * 0.98;
}
double calculateTotal() {
if (basePrice() > 1000) {
return basePrice() * 0.95;
}
return basePrice() * 0.98;
}
double basePrice() {
return quantity * itemPrice;
}
Variable-Level Refactorings:
Rename Variable
d = 10
elapsed_time_in_days = 10
Split Temporary Variable
double temp = 2 * (height + width);
System.out.println(temp);
temp = height * width;
System.out.println(temp);
double perimeter = 2 * (height + width);
System.out.println(perimeter);
double area = height * width;
System.out.println(area);
Class-Level Refactorings:
Extract Class
class Person {
String name;
String officeAreaCode;
String officeNumber;
String getTelephoneNumber() {
return "(" + officeAreaCode + ") " + officeNumber;
}
}
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
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):
pass
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-Specific Refactorings
Use Modern Java Features:
Replace Anonymous Class with Lambda
list.sort(new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
list.sort((a, b) -> a.compareTo(b));
list.sort(String::compareTo);
Use Streams API
List<String> result = new ArrayList<>();
for (String s : list) {
if (s.length() > 3) {
result.add(s.toUpperCase());
}
}
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
Replace String Concatenation
String result = "";
for (String s : list) {
result += s + ", ";
}
StringBuilder result = new StringBuilder();
for (String s : list) {
result.append(s).append(", ");
}
String result = String.join(", ", list);
Use Optional
public User findUser(int id) {
User user = database.getUser(id);
return user != null ? user : new User();
}
public Optional<User> findUser(int id) {
return Optional.ofNullable(database.getUser(id));
}
Replace Type Code with Enum
public static final int TYPE_A = 1;
public static final int TYPE_B = 2;
public enum Type {
A, B
}
5. Python-Specific Refactorings
Use List Comprehensions
result = []
for item in items:
if item > 0:
result.append(item * 2)
result = [item * 2 for item in items if item > 0]
Use Collections Module
counts = {}
for item in items:
if item in counts:
counts[item] += 1
else:
counts[item] = 1
from collections import Counter
counts = Counter(items)
Use Context Managers
file = open('file.txt')
data = file.read()
file.close()
with open('file.txt') as file:
data = file.read()
Use f-strings
message = "Hello, %s! You are %d years old." % (name, age)
message = f"Hello, {name}! You are {age} years old."
Use Type Hints
def process(data):
return [x * 2 for x in data]
def process(data: list[int]) -> list[int]:
return [x * 2 for x in data]
Use Dataclasses
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})"
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
6. Clean Code Principles
Naming:
int d;
int elapsedTimeInDays;
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<>();
for (int[] x : theList) {
if (x[0] == 4) {
list1.add(x);
}
}
return list1;
}
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:
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
if (employee.isEligibleForFullBenefits())
7. Performance Refactorings
Algorithm Optimization:
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):
return len(arr) != len(set(arr))
Lazy Evaluation:
List<Integer> results = list.stream()
.map(this::expensiveOperation)
.collect(Collectors.toList());
return results.get(0);
return list.stream()
.map(this::expensiveOperation)
.findFirst()
.orElse(null);
Memoization:
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
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. Refactoring Workflow
Step-by-step process:
- Identify: Find code smell or improvement opportunity
- Plan: Decide which refactoring to apply
- Test: Ensure tests exist and pass
- Refactor: Make one small change
- Test: Run tests again
- Commit: Save working state
- Repeat: Continue with next refactoring
Example workflow:
git checkout -b refactor/improve-user-service
mvn test
mvn test
git commit -m "refactor: extract validateUser method"
9. Refactoring Checklist
Before refactoring:
During refactoring:
After refactoring:
10. LeetCode-Specific Refactoring
Optimize brute force:
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[]{};
}
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:
def solve(self, grid):
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):
def preprocess(self, grid):
def compute(self, data):
def format_output(self, result):
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
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