본문 바로가기
Java Study

리팩토링(Refactoring)

by xogns93 2024. 7. 10.

리팩토링(Refactoring)은 기존의 코드의 기능을 변경하지 않으면서, 코드를 더 이해하기 쉽고, 유지보수하기 쉽게 만드는 일련의 과정입니다. 리팩토링의 주요 목적은 코드의 품질을 향상시키고, 코드를 더 효율적이고 읽기 쉽게 만들며, 버그를 줄이는 것입니다.

 

리팩토링의 필요성

  1. 코드 가독성 향상: 잘 읽히는 코드는 더 쉽게 이해되고, 유지보수하기 쉬워집니다.
  2. 코드 중복 제거: 반복되는 코드를 제거하여 유지보수를 용이하게 합니다.
  3. 변경 용이성: 코드 구조를 개선하여 새로운 기능 추가나 수정이 더 쉽게 이루어질 수 있습니다.
  4. 버그 감소: 코드가 더 명확해지면 버그가 발생할 가능성이 줄어듭니다.
  5. 성능 향상: 리팩토링을 통해 성능을 최적화할 수 있습니다.

리팩토링의 기본 원칙

  1. 작은 단계로 진행: 큰 변화를 한 번에 하지 말고, 작은 단계로 조금씩 변경합니다. 이렇게 하면 변경으로 인한 버그를 최소화할 수 있습니다.
  2. 기존 기능 유지: 리팩토링 과정에서 기존의 기능이 변경되지 않도록 해야 합니다. 이를 위해 단위 테스트(Unit Test)를 활용하여 기능을 검증합니다.
  3. 테스트 주도 개발(TDD)과 병행: 리팩토링 전후에 충분한 테스트를 작성하여 기능이 올바르게 동작하는지 확인합니다.

일반적인 리팩토링 기법

  1. 메서드 추출 (Extract Method): 긴 메서드의 일부분을 별도의 메서드로 추출하여 가독성을 높입니다.
  2. 변수 이름 변경 (Rename Variable): 의미 있는 변수 이름을 사용하여 코드의 가독성을 높입니다.
  3. 클래스 추출 (Extract Class): 하나의 클래스가 여러 책임을 가지고 있을 때, 이를 분리하여 각각의 책임을 가지는 클래스로 만듭니다.
  4. 메서드 이동 (Move Method): 관련 있는 클래스나 객체로 메서드를 이동시켜 응집도를 높입니다.
  5. 조건문 단순화 (Simplify Conditionals): 복잡한 조건문을 단순화하여 가독성을 높입니다.
  6. 루프 단순화 (Simplify Loops): 복잡한 루프를 단순화하여 가독성을 높입니다.

 

 

리팩토링 예제 (Java)

 

다음은 소수를 구하는 코드의 리팩토링 전후의 간단한 예제입니다.

 

일반적인 소수를 구하는 평범한 코드를 보면 소수를 구하기까지의 반복 횟수가 4950번이 나옵니다.

public class Primenumbers {
	int num = 100;

	public static void main(String[] args) {
		Primenumbers pn = new Primenumbers();

		int total_count = 0;

		for (int i = 1; i <= pn.num; i++) {
			int count = 0; // 카운트 초기화
										  
			for (int j = 1; j < i; j++) { // j를 현재 i의 숫자까지
				total_count++;
				if (i % j == 0) { // i를 j로 나눠서 나머지 값이 0이면 카운트 증가
					count++;
				}
			}

			if (count == 1) {
				// System.out.println(i);
				System.out.printf("%d \n", i);
			}
		}
		System.out.printf("total_count : %d \n", total_count);
	}
}

 

 

아래는 에라토스테네스의 체를 활용하여 리팩토링한 예제입니다

반복횟수가 212번으로 현저히 줄어든걸 볼 수 있습니다.

public class PrimeNumbers {
    public static void main(String[] args) {
        int limit = 100;
        boolean[] isPrime = new boolean[limit + 1];
        int total_count = 0;
        // Initialize all numbers as prime
        for (int i = 2; i <= limit; i++) {
        	total_count++;
            isPrime[i] = true;
        }
        // Implement Sieve of Eratosthenes
        for (int factor = 2; factor * factor <= limit; factor++) {
        	total_count++;
            if (isPrime[factor]) {
                for (int j = factor * factor; j <= limit; j += factor) {
                	total_count++;
                    isPrime[j] = false;
                }
            }
        }
        System.out.printf("\n Total Count:%d ", total_count);
        // Print all prime numbers
        System.out.println("\nPrime numbers between 1 and 100:");
        for (int i = 2; i <= limit; i++) {
            if (isPrime[i]) {
                System.out.print(i + " ");
            }
        }
    }
}

 

'Java Study' 카테고리의 다른 글

게터(getter)와 세터(setter) 메서드  (0) 2024.07.15
클래스(static) 메서드와 인스턴스 메서드  (0) 2024.07.11
"섀도잉(Shadowing)"과 "하이딩(Hiding)"  (0) 2024.07.08
캐스팅 ( Casting )  (1) 2024.07.05
필드(Field)  (0) 2024.06.28