Extract Method
그룹으로 함꼐 묶을 수 있는 코드 조각이 있으면 코드의 목적이 잘 드러나도록 메소드의 이름을 지어 별도의 메소드로 뽑아낸다.
동기
지나치게 긴 메소드나 주석이 필요한 코드를 보면 그 부분을 하나의 메소드로 뽑는다.(Martin Fowler 曰).
- 메소드가 잘게 쪼개져 있을 때 다른 곳에서 사용하기 좋다.
- High-level의 메소드를 보면 주석을 읽는 것 같은 느낌이 들도록 할 수 있다.
- 오버라이드 하는 것도 훨씬 쉽다.
작은 메소드들은 작명을 잘했을 때 그 진가를 드러내므로 이름을 잘 짓도록 하자.
절차
- 메소드를 새로 만들고, 무엇을 하는지를 나타내도록 이름을 정한다.
- 원래 메소드에서 뽑아내고자 했던 부분을 복사하여 새 메소드로 옮긴다.
- 원래 메소드에서 사용되고 있는 지역변수가 뽑아낸 코드에 있는지 확인한다. 있으면 새로운 메소드의 임시변수로 선언한다.
- 뽑아낸 코드 안에서 지역변수의 값이 변화는지 확인한다. 만약에 하나의 지역변수만 수정 된다면, 뽑아낸 코드를 질의(query)로 보고, 수정된 결과를 관련된 변수에 대입할 수 있는지 본다. 이렇게 하는 것이 이상하거나, 값이 수정되는 지역변수가 두개 이상 있다면 쉽게 메소드로 추출할 수 없는 경우이다. 이럴 때는 Split Temporary Variable을 사용한 다음 다시 시도해야 한다. 임시변수는 Replace Temp with Query로 제거할 수 있다.
- 뽑아낸 코드에서 읽기만 하는 코드는 파라미터로 넘긴다.
- 지역변수와 관련된 사항을 다룬 후에는 컴파일을 한다.
- 원래 메소드에서 새로 만든 메소드를 호출하도록 바꾼다.
- 컴파일과 테스트를 한다.
예제 : 지역변수가 없는 경우
위 코드에서 처음에 수정할 부분은 노란색으로 표시된 부분입니다. 매우 단순한 경우이기 때문에 잘라서 새로운 메소드로 붙여넣고 저 노란 부분에서 새로운 메소드를 호출하면 되겠습니다.
이클립스에서 리팩토링 할 부분을 드래그 한 상태에서 Alt + Shift + m 을 클릭합니다. 그리고 새로운 메소드의 이름을 적어 줍니다.
그리고 OK 버튼을 클릭하면...
짠... 멋지게 처리해 주는 군요.. 주석만 빼고. ^^; 주석은 Ctrl + d (행삭제)를 사용하여 지워줍시다.
예제 : 지역변수가 포함되어 있는 경우
지역변수가 옮겨질 코드에 들어있는 경우 중에 가장 쉬운 경우가 바로 그 지역변수를 읽기만 하는 경우입니다. 이런 경우에는 변수를 파라미터로 넘겨주면 됩니다.
이번에는 저 노란 부분을 메소드로 뽑아 낼 것입니다. 보아하니 _name이라는 변수와 outstanding이라는 변수를 사용하고 있는데 outstanding만 지역변수고 _name은 필드네요. 따라서 outstanding만 넘겨주면 되겠습니다. 메소드 이름은 printDetails로 하는군요. 이번에도 뽑아내고 싶은 부분을 드래그 하고 Alt + Shift + m ...와오..
똑똑한 이클립스... 파라미터가 필요한 줄 알고.. 그것도 딱 지역변수만.. 아 정말 똑똑하네요. 역시 OK만 누르면..
대단합니다. 이클립스.
예제 : 지역변수에 다른 값을 여러 번 대입하는 경우 (마지막입니다. :)
이 경우는 복잡한데 이런 경우 중 임시변수에 대해서만 생각을 해봅니다. (파라미터에 다른 값을 대입하는 코드가 있다면 즉시 Remove Assignments to Parameters를 적용해야 한다.)만약에 그 임시변수가 뽑아내는 코드에서만 사용이 된다면 뽑아낸 코드로 그냥 그 임시변수까지 이동하면 되겠습니다. 하지만 그 임시변수가 뽑아내는 코드 밖에서도 사용이 된다면 뽑아낸 코드에서 그 값을 리턴해 주어야 합니다.
노란 부분을 보시면 each라는 임시변수는 뽑아내게 될 코드 안에서만 사용되는 것을 볼 수 있습니다. 그렇기 때문에 그냥 이동 시키면 되겠지요
위에 보이는 노란 부분이 뽑아 낼 부분입니다. 저 중에 each는 노란 부분에서만 쓰이기 때문에 당연히 그냥 빼내는 메소드로 이동하면 되겠습니다. 하지만 문제는 outstanding인데 이 변수가 printDetails 메소드에서 사용되고 있습니다. 따라서 위의 코드에서 계산 부분의 코드를 뽑아내고 outstaning의 값을 리턴하도록 합니다.
이번에는 이클립스의 덕을 잘 못보겠더군요.
임시변수가 너무 많아 코드를 뽑아내기 어려울 때는 Replace Temp with Query를 사용하여 임시변수를 줄이고 어떻게 해봐도 여전히 난처할 때는 Replace Method with Method Object를 사용한다. 이 리팩토링은 임시변수가 얼마나 많든, 그리고 뭘 하든 상관하지 않는다.