코드 리팩토링(Refactoring)은 기능을 변경하지 않으면서 코드의 구조를 개선하는 과정입니다.
즉, 코드의 가독성을 높이고, 유지보수를 쉽게 만들며, 성능을 최적화하는 과정을 의미합니다.
✅ 기능은 그대로 유지하면서 코드 품질을 개선
✅ 가독성, 유지보수성, 확장성 향상
✅ 중복 코드 제거, 불필요한 복잡성 제거
📌 리팩토링의 목적은 "코드를 더 깔끔하고 효율적으로 만들기"
✅ 가독성 향상 → 코드를 읽기 쉽게 만들어 유지보수 용이
✅ 유지보수 비용 절감 → 코드 구조를 개선하면 버그 수정 및 기능 추가가 쉬워짐
✅ 코드 중복 제거 → 중복 코드를 최소화하여 코드 길이 감소
✅ 성능 최적화 → 불필요한 연산을 줄이고, 효율적인 코드 작성 가능
✅ 버그 예방 → 코드가 명확해지면 실수로 인한 버그 발생 가능성이 줄어듦
📌 리팩토링을 하지 않으면 코드가 점점 복잡해지고 유지보수가 어려워짐!
📌 Before (중복 코드가 존재)
public class Discount {
public double getDiscountedPrice(String type, double price) {
if (type.equals("STUDENT")) {
return price * 0.9;
} else if (type.equals("SENIOR")) {
return price * 0.85;
} else {
return price;
}
}
}
📌 After (중복 제거 및 개선)
public class Discount {
public double getDiscountedPrice(String type, double price) {
double discountRate = switch (type) {
case "STUDENT" -> 0.9;
case "SENIOR" -> 0.85;
default -> 1.0;
};
return price * discountRate;
}
}
✅ 중복된 return price * 0.XX;
코드 제거하여 유지보수 용이
📌 Before (의미 없는 변수명)
public void process(int a, int b) {
int c = a + b;
System.out.println(c);
}
📌 After (가독성 향상)
public void printSum(int num1, int num2) {
int sum = num1 + num2;
System.out.println(sum);
}
✅ 의미 없는 a
, b
, c
대신 num1
, num2
, sum
을 사용하여 가독성 향상
📌 Before (하나의 긴 메서드)
public class Order {
public void processOrder() {
// 사용자 인증
System.out.println("사용자 인증 완료");
// 결제 처리
System.out.println("결제 완료");
// 주문 정보 저장
System.out.println("주문 정보 저장");
}
}
📌 After (단일 책임 원칙 적용)
public class Order {
public void processOrder() {
authenticateUser();
processPayment();
saveOrder();
}
private void authenticateUser() {
System.out.println("사용자 인증 완료");
}
private void processPayment() {
System.out.println("결제 완료");
}
private void saveOrder() {
System.out.println("주문 정보 저장");
}
}
✅ 하나의 긴 메서드를 여러 개의 작은 메서드로 분리하여 유지보수 용이
📌 Before (매직 넘버 사용)
public double calculateInterest(double amount) {
return amount * 0.05; // 5% 금리 (하드코딩된 값)
}
📌 After (상수 사용)
public class InterestCalculator {
private static final double INTEREST_RATE = 0.05;
public double calculateInterest(double amount) {
return amount * INTEREST_RATE;
}
}
✅ 매직 넘버(0.05)를 INTEREST_RATE
상수로 정의하여 가독성 및 유지보수성 향상
📌 Before (불필요한 if-else)
public String getStatus(boolean isActive) {
if (isActive) {
return "Active";
} else {
return "Inactive";
}
}
📌 After (삼항 연산자 활용)
public String getStatus(boolean isActive) {
return isActive ? "Active" : "Inactive";
}
✅ 간단한 조건문은 삼항 연산자를 사용하여 가독성 향상
📌 Before (Java switch 문)
public String getDay(int day) {
switch (day) {
case 1: return "Monday";
case 2: return "Tuesday";
case 3: return "Wednesday";
default: return "Invalid Day";
}
}
📌 After (Kotlin when 문)
fun getDay(day: Int): String {
return when (day) {
1 -> "Monday"
2 -> "Tuesday"
3 -> "Wednesday"
else -> "Invalid Day"
}
}
✅ 코틀린의 when
문을 사용하여 가독성과 유지보수성 향상
✅ 작은 단위로 리팩토링 진행 → 한 번에 너무 많은 변경 X
✅ 테스트 코드가 존재하는 상태에서 리팩토링 진행 → 기능 유지 보장
✅ 중복 코드 제거 & 가독성 향상 우선
✅ SOLID 원칙 적용하여 객체지향적인 코드 작성
✅ 불필요한 if-else 문을 최소화하고, 삼항 연산자, switch-case 최적화
📌 리팩토링 후에도 기존 기능이 정상적으로 동작하는지 반드시 테스트!
📌 리팩토링 ≠ 성능 최적화
📌 예: 성능 최적화를 위한 리팩토링 (Stream API 활용)
// Before (for문 사용)
int sum = 0;
for (int num : numbers) {
sum += num;
}
// After (Stream API 활용)
int sum = numbers.stream().mapToInt(Integer::intValue).sum();
✅ Stream API를 활용하여 코드 가독성 + 성능 향상
✅ 코드 리팩토링은 "기능은 유지하면서 코드 품질을 개선하는 과정"
✅ 중복 코드 제거, 가독성 향상, 유지보수성 증가 등의 효과가 있음
✅ 작은 단위로 진행하고, 기존 기능이 유지되는지 반드시 테스트해야 함
✅ SOLID 원칙, Clean Code 원칙을 적용하여 효과적인 리팩토링 수행