800===Dev Docs and License/Design Pattern

더 나은 Java 코드 리팩토링 가이드 🛠️

블로글러 2024. 11. 13. 23:52

안녕하세요! 오늘은 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));
}

리팩토링 체크리스트 ✅

  1. 코드 악취 찾기
    • 중복된 코드가 있는가?
    • 메소드가 너무 긴가?
    • 클래스가 너무 많은 책임을 가지고 있는가?
  2. 테스트 코드 준비
    • 리팩토링 전 테스트 코드 작성
    • 리팩토링 중간중간 테스트 실행
  3. 점진적 개선
    • 한 번에 큰 변화보다는 작은 단계로 나누어 진행
    • 각 단계마다 테스트 확인

도구 활용하기 🔧

  1. IDE의 리팩토링 기능
    • IntelliJ IDEA
    • Eclipse
    • VS Code
  2. 정적 분석 도구
    • SonarQube
    • PMD
    • CheckStyle

마치며 🎁

리팩토링은 한 번에 완벽해질 수 없습니다. 지속적인 관심과 개선이 필요한 과정입니다. "깨진 유리창 이론"처럼, 작은 개선부터 시작해보세요!


References:

  1. Clean Code by Robert C. Martin
  2. Refactoring: Improving the Design of Existing Code by Martin Fowler
  3. Effective Java by Joshua Bloch
728x90