Refactoring 리팩토링

Yuno·2024년 8월 14일

JavaSpring

목록 보기
15/16

✏️ 리팩토링 이란?

기존 코드를 개선하여 읽기 쉽고 유지보수하기 쉽게 만드는 과정
리팩토링을 통해 코드의 구조를 변경하되, 외부 동작은 그대로 유지하는 것이 목표.
이를 통해 코드의 품질을 높이고 버그를 줄이며, 새로운 기능을 추가 하기 쉬운 기반을 만들 수 있음


📌 리팩토링의 주요 목표

  1. 코드 가독성 향상 : 코드가 이해하기 쉽고 명확하게 작성되어야 함
  2. 유지보수성 향상 : 코드를 수정하거나 기능을 추가하기 쉬워야 함
  3. 중복 제거 : 중복된 코드를 제거하여 코드의 일관성을 높이고 유지보수를 용이하게 함
  4. 모듈화 : 코드의 기능을 잘 정의된 모듈로 나누어 재사용성을 높임

📌 리팩토링의 일반적인 기법

  1. 메서드 추출(Extract Method)
  • 복잡한 메서드를 여러 개의 작은 메서드로 분리하여 읽기 쉽게 만듬
public void printOwing(double amount) {
	// 기존 코드
    printBanner();
    // 세부 사항 추출
    printDetails(amount);
}

private void printDetails(double amount) {
	System.out.println("총 금액은 " + amount + "입니다.");
}
  1. 변수 추출(Extract Variable)
  • 복잡한 표현식을 변수로 분리하여 코드의 의미를 명확히 함
double basePrice = quantity * itemPrice;
double discount = (basePrice > 1000) ? basePrice * 0.1 : 0;
double finalPrice = basePrice - discount;
  1. 조건문 분해(Decompose Conditional)
  • 복잡한 조건문을 메서드로 분리하여 가독성을 높입니다.
if (isDiscountable()) {
	applyDiscount();
}
  1. 클래스 추출(Extrack Class)
  • 하나의 클래스가 너무 많은 책임을 가지는 경우, 이를 여러 개의 클래스로 나눔
public class Order {
	private Customer customer;
    private List<Item> items;
    
    public void addItem(Item item) { ... }
    public double getTotal() { ... }
}
  1. 클래스 통합(Inline Class)
  • 너무 많은 책임을 가진 클래스나 사용되지 않는 클래스를 통합하여 코드 복잡도를 줄임
public class Customer {
	private String name;
    private String address;
    // 인라인
}
  1. 인터페이스 분리(Split Interface)
  • 큰 인터페이스를 여러 개의 작은 인터페이스로 나누어 각 인터페이스가 하나의 책임만 가지도록 함
public interface Shape {
	void draw();
    double area();
}

public interface Drawable {
	void draw();
}
  1. 기본 데이터 타입을 객체로 변경(Prinitive Obsession)
  • 기본 데이터 타입을 객체로 변경하여 데이터와 관련된 기능을 함께 포함시킴
public class Money {
	private final BigDecimal amount;
    private final Currency currency;
    
    public Money(BigDecimal amount, Currency currency) {
    // Getter 및 메서드
    }
}

📌 리팩토링 적용 예시

기존 코드

public class OrderProcessor {
	public void processOrder(Order order) {
    	double total = 0;
        for (Item item : order.getItems()) {
        	total += item.getPrice();
        }
        if (total > 1000) {
        	total *= 0.9;
        }
    }
}

리팩토링 후

public class OrderProcessor {
	public void processOrder(Order order) {
    	double total = calculateTotal(order);
        double discountedTotal = applyDiscountIfNeeded(total);
    }
    
    private double calculateTotal(Order order) {
    	return order.getItems().stream()
        			.mapToDouble(Item::getPrice)
                    .sum();
    }
    
    private double applyDiscountIfNeeded(double total) {
    	return (total > 1000) ? total * 0.9 : total;
    }
}
profile
Hello World

0개의 댓글