Home 리팩토링(3)_method 정리
Post
Cancel

리팩토링(3)_method 정리

Refactoring (3)_method 정리 - 1st

1. 매서드 추출 (Extract Method)

  • 어떤 코드를 그룹으로 묶어도 괜찮다고 판단이 된다면, 그 코드를 빼내어 목적을 잘 나타내는 직관적인 이름의 method로 만들자.

방법

  • 목적에 부합하는 이름의 새로운 method를 생성하자. 이 때 이름은 원리가 아닌 기능을 나타내는 이름으로 한다.
    • method로 빼낼 코드가 한 줄의 명령이나 함수 호출 같이 아주 간단한 것이라면 새 method명을 통해 그 코드의 기능(목적)을 더 잘 드러낼 수 있을 때만 추출을 실시하자. 더 이해하기 쉬운 이름으로 추출하지 못할 경우 코드를 추출하지 말아야 한다.
  • 기존 method에서 빼낸 코드를 새로 생성한 method로 복사하자
  • 빼낸 코드에서 기존 method의 모든 지역변수 참조를 찾자. 그것들을 새로 생성한 method의 지역변수나 매개변수로 사용할 것이다.
  • 빼낸 코드 안에서만 사용되는 임시변수가 있는지 파악해서 있다면 그것들을 새로 생성한 method안에 임시변수로 선언
  • 추출 코드에 의해 변경되는 지역변수가 있는지 파악하자. 만약 하나의 지역변수만 변경된다면 추출 코드를 method 호출처럼 취급할 수 있는지 알아내고, 그 결과를 변수에 대입할 수 있는지 알아내자. 이렇게 하기 까다롭거나 둘 이상의 지역변수가 변경될 때는 method를 추출하기 위해 먼저 임시변수 분리 등의 기법을 적용해야 할 수 있다. 임시변수를 제거하려면 임시변수를 method 호출로 전환 기법을 적용하면 된다.
  • 빼낸 코드에서 읽어들인 지역변수를 대상 method에 매개변수로 전달한다.
  • 모든 지역변수 처리를 완료했으면 컴파일을 실시하자
  • 원본 method안에 있는 빼낸 코드 부분을 새로 생성한 method 호출로 수정하자
  • 컴파일 및 테스트를 진행한다.

2. 매서드 내용 직접 삽입 (Inline Method)

  • method 기능이 너무 단순해서 매서드명만 봐도 너무 뻔한 내용일 때, 그 method의 기능을 호출하는 method에 내용을 넣고 그 메서드는 삭제하자

방법

  • 메서드가 재정의되어 있지 않은지 확인
    • 그 메서드가 하위클래스에 재정의되어 있다면 없어진 매서드를 재정의하는 일이 생겨서는 안되기 때문에 메서드 내용 직접 삽입을 실시하지 않는 것이 좋다.
  • 그 메서드를 호출하는 부분을 모두 확인
  • 각 호출 부분을 메서드 내용으로 교체
  • 테스트 진행
  • 정의된 메서드를 삭제

3. 임시변수 내용 직접 삽입 (Inline Temp)

  • 간단한 수식을 대입받는 임시변수로 인해 다른 리팩토링 기법 적용이 힘들 땐, 그 임시변수를 참조하는 부분을 전부 수식으로 치환하자
1
2
3
4
5
6
7
8
// 간단한 예시

/* 리팩토링 이전 */
double totalPrice = Order.totalPrice();
return (10000 < totalPrice);

/* 리팩토링 이후 */
return (10000 < Order.totalPrice());

방법

  • 대입문의 우변에 문제가 없는지 확인한다
  • 문제가 없다면 임시변수를 final로 선언하고 컴파일을 진행
    • final로 선언함으로서 임시변수에는 값을 한 번만 대입할 수 있다.
  • 그 임시변수를 참조하는 모든 부분을 찾아서 대입문 우변의 수식으로 변환
  • 하나씩 수정을 할 때마다 컴파일 및 테스트 진행
  • 임시변수 선언과 대입문을 삭제
  • 컴파일 및 테스트 진행

4. 임시변수를 매서드 호출로 전환 (Replace Temp with Query)

  • 수식의 결과를 저장하는 임시변수가 있을 땐, 그 수식을 빼내어 메서드로 만든 후, 임시변수 참조 부분을 전부 수식으로 교체하자. 새로 만든 메서드는 다른 메서드에서도 호출이 가능하다.
/* 리팩토링 이전 */
double basePrice = itemCnt * itemPrice;
if(basePrice > 10000)
    return basePrice * 0.95;
else
    return basePrice * 0.98;



/* 리팩토링 이후 */
double basePrice() {
	return itemCnt * itemPrice;
}
if(basePrice() > 10000)
    return basePrice() * 0.95;
else
    return basePrice() * 0.98;

동기

  • 임시변수는 일시적이고 적용이 국소적인 범위로 제한이 된다. 임시변수는 자신이 속한 메서드의 안에서만 인식되므로, 그 임시변수에 접근하려면 코드는 길어지게 된다. 이럴 때, 임시변수를 매서드 호출로 수정하면 클래스 안 모든 메서드가 그 정보에 접근이 쉬워진다.

방법

  • 값이 한 번만 대입되는 임시변수를 확인
    • 값이 여러 번 대입되는 임시변수가 있다면 임시변수 분리 기법 실시를 고려해야 한다.
  • 그 임시변수를 final로 선언
    • 임시변수엔 값을 한 번만 대입할 수 있다.
  • 컴파일을 실시
  • 대입문 우변을 빼내어 메서드로 변환
    • 처음엔 메서드를 private로 선언. 그 후 더 여러 곳에서 사용하게 되면 접근 제한을 완화한다.
    • 추출 메서드에 문제는 없는지 확인을 해야한다. 만약 **객체 변경 등의 문제가 있다면 상태 변경 메서드와 값 반환 메서드를 분리 기법을 실시.**
  • 컴파일 및 테스트 진행
  • 임시변수를 대상으로 임시변수 내용을 직접 삽입 기법을 실시

참고자료

  • 리팩토링_코드 품질을 개선하는 객체지향 사고법 _마틴파울러 저