안녕하세요! 오늘은 Java 코드를 더 깔끔하고 유지보수하기 좋게 만드는 리팩토링 방법에 대해 알아보겠습니다.
리팩토링이란? 🤔
리팩토링은 마치 방 청소와 같습니다:
- 외부 동작은 그대로 유지하면서
- 내부 구조를 개선하는 작업
- 코드의 가독성과 유지보수성을 높이는 과정
주요 리팩토링 기법 💡
1. 긴 메소드 분리하기
// Before
public void processOrder(Order order) {
// 100줄의 복잡한 코드...
}
// After
public void processOrder(Order order) {
validateOrder(order);
calculateTotalPrice(order);
applyDiscount(order);
saveOrder(order);
sendConfirmation(order);
}
2. 의미 있는 이름 사용하기
// Bad
public class Proc {
private int d; // days
public void proc() {} // process
}
// Good
public class OrderProcessor {
private int daysToExpire;
public void processOrder() {}
}
3. 매직 넘버 제거
// Before
if (employee.getYearsOfService() > 5) {
bonus = salary * 0.1;
}
// After
private static final int SENIOR_EMPLOYEE_YEARS = 5;
private static final double SENIOR_BONUS_RATE = 0.1;
if (employee.getYearsOfService() > SENIOR_EMPLOYEE_YEARS) {
bonus = salary * SENIOR_BONUS_RATE;
}
4. 조건문 단순화
// Before
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
if (!customer.isVip()) {
if (order.getTotal() < 50) {
charge = 10;
}
}
}
// After
private boolean isOffSeason(Date date) {
return date.before(SUMMER_START) || date.after(SUMMER_END);
}
private boolean isSmallOrder(Order order) {
return order.getTotal() < 50;
}
charge = isOffSeason(date) && !customer.isVip() && isSmallOrder(order) ? 10 : 0;
5. 빌더 패턴 활용
// Before
User user = new User();
user.setName("John");
user.setAge(25);
user.setEmail("john@example.com");
// After
User user = User.builder()
.name("John")
.age(25)
.email("john@example.com")
.build();
실전 리팩토링 예시 📝
1. 단일 책임 원칙 적용
// Before
public class OrderService {
public void processOrder(Order order) {
// 주문 처리
// 이메일 발송
// 재고 관리
// 통계 업데이트
}
}
// After
public class OrderService {
private EmailService emailService;
private InventoryService inventoryService;
private StatisticsService statisticsService;
public void processOrder(Order order) {
processOrderInternal(order);
emailService.sendConfirmation(order);
inventoryService.updateStock(order);
statisticsService.updateStats(order);
}
}
2. 옵셔널 활용
// Before
public User findUser(String id) {
User user = userRepository.findById(id);
if (user == null) {
throw new UserNotFoundException(id);
}
return user;
}
// After
public User findUser(String id) {
return userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
}
리팩토링 체크리스트 ✅
- 코드 악취 찾기
- 중복된 코드가 있는가?
- 메소드가 너무 긴가?
- 클래스가 너무 많은 책임을 가지고 있는가?
- 테스트 코드 준비
- 리팩토링 전 테스트 코드 작성
- 리팩토링 중간중간 테스트 실행
- 점진적 개선
- 한 번에 큰 변화보다는 작은 단계로 나누어 진행
- 각 단계마다 테스트 확인
도구 활용하기 🔧
- IDE의 리팩토링 기능
- IntelliJ IDEA
- Eclipse
- VS Code
- 정적 분석 도구
- SonarQube
- PMD
- CheckStyle
마치며 🎁
리팩토링은 한 번에 완벽해질 수 없습니다. 지속적인 관심과 개선이 필요한 과정입니다. "깨진 유리창 이론"처럼, 작은 개선부터 시작해보세요!
References:
- Clean Code by Robert C. Martin
- Refactoring: Improving the Design of Existing Code by Martin Fowler
- Effective Java by Joshua Bloch
728x90
'800===Dev Docs and License > Design Pattern' 카테고리의 다른 글
Locality of Behavior (행위의 국소성) 😊 (0) | 2024.11.17 |
---|---|
실전 Java 코드 리팩토링 상세 가이드 🔧 (2) | 2024.11.13 |
Observer Pattern with Java (0) | 2024.05.30 |
Clean Architecture (0) | 2024.05.28 |
Singleton Pattern with Java (0) | 2024.05.28 |