관리 메뉴

너와 나의 스토리

[리팩터링] Inline Function 예제로 이해하는 "함수 인라인하기" 본문

개발/Refactoring

[리팩터링] Inline Function 예제로 이해하는 "함수 인라인하기"

노는게제일좋아! 2021. 9. 8. 15:16
반응형

함수를 인라인하는 상황

  • 상황 1: 함수 본문이 이름만큼 명확한 경우
    • 함수를 제거
      • 불필요한 간접 호출은 거슬릴 뿐
      • 함수 생성해서 간접 호출하던 것을 합치는 것
    • 예:
      • int rating(int cost) {
            return moreThanFiveCost(cost) ? 2 : 1;
        }
        
        boolean moreThanFiveCost(int cost) {
            return cost > 5;
        }
  • 상황 2: 잘못 추출된 함수들도 다시 인라인한다.
    • 잘못 추출된 함수들을 원래 함수로 합친 다음, 필요하면 원하는 형태로 다시 추출하는 것
  • 상황 3: 간접 호출을 너무 과하게 쓴 코드도 흔한 인라인 대상이다
    • 다른 함수로 단순히 위임하기만 하는 함수들이 너무 많아서 위임 관계가 복잡하게 얽혀 있으면 인라인 해버린다.

 

절차

  1. 다형 메서드(polymorphic method)인지 확인한다.
    • 서브 클래스에서 오버라이드하는 메서드는 인라인하면 안 된다.
      • * 다형성: 하단 설명 참고
  2. 인라인할 함수를 호출하는 곳을 모두 찾는다.
  3. 각 호출문을 함수 본문으로 교체한다.
  4. 하나씩 교체할 때마다 테스트한다.
    • 인라인 작업을 한 번에 처리할 필요는 없다.
    • 인라인하기가 까다로운 부분이 있다면 일단 남겨두고 여유가 생길 때마다 틈틈이 처리한다.
  5. 함수 정의(원래 함수)를 삭제한다.

 

예제를 보며 리팩터링을 해보자!

  • 예제 코드:
public class Animal {

    public void action() {
        List<String> features = new ArrayList<>();
        gatherFeatures(features);
        
        // do something

        sound();
    }

    public void sound() {
        System.out.println("Animal is making a sound");
    }
    
    private void gatherFeatures(List<String> features) {
        features.add("Sensitive");
        features.add("Independent");
    }
}

public class Cat extends Animal {

    @Override
    public void sound() {
        System.out.println("Meow");
    }

}
  • Animal 클래스의 action 함수를 리팩터링 해보자.
  • 먼저 gatherFeautres()라는 함수가 보인다.
    • public void action() {
          List<String> features = new ArrayList<>();
          features.add("Sensitive");
          features.add("Independent");
      
          // do something
      
          sound();
      }
    • 다음과 같이 함수를 인라인해도 코드의 의미가 명확하다. 
  • 다음으로는 sound()라는 함수가 보인다.
    • 이는 하위 클래스에서 오버라이드하는 함수이기 때문에 인라인 해서는 안된다.

 

 

 

* 다형성

  • 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미
  • 자바에서는 이러한 다형성을 부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현하고 있다.
class Animal { ... }

class Cat extends Animal { ... }

class Dog extends Animal { ... }

...

Animal animal = new Animal(); // 허용

Cat cat = new Cat();   // 허용

Animal animal = new Cat();  // 허용

Cat cat = new Animal();  // 오류 발생

 

 

 

 

참고:

- [리팩터링 2판]

 

반응형
Comments