절차
- 선택한 함수가 현재 컨텍스트에서 사용 중인 모든 프로그램 요소를 살펴본다. 이 요소들 중에도 함께 옮겨야 할 게 있는지 고민해 본다.
- 선택한 함수가 다형 메서드인지 확인한다.
- 선택한 함수를 타깃 컨텍스트로 복사한다. 타깃 함수가 새로운 터전에 잘 자리 잡도록 다듬는다.
- 정적 분석을 수행한다.
- 소스 컨텍스트에서 타깃 함수를 참조할 방법을 찾아 반영한다.
- 소스 함수를 타깃 함수의 위임 함수가 되도록 수정한다.
- 테스트한다.
- 소스 함수를 인라인할지 고민해본다.
절차
- 소스 필드가 캡슐화되어 있지 않다면 캡슐화한다.
- 테스트한다.
- 타깃 객체에 필드를 생성한다.
- 정적 검사를 수행한다.
- 소스 객체에서 타깃 객체를 참조할 수 있는지 확인한다.
- 접근자들이 타깃 필드를 사용하도록 수정한다.
- 테스트한다.
- 소스 필드를 제거한다.
- 테스트한다.
절차
- 반복 코드가 함수 호출 부분과 멀리 떨어져 있다면 문장 슬라이드하기를 적용해 근처로 옮긴다.
- 타깃 함수를 호출하는 곳이 한 곳뿐이면, 단순히 소스 위치에서 해당 코드를 잘라내어 피호출 함수로 복사하고 테스트한다. 이 경우라면 나머지 단계는 무시한다.
- 호출자가 둘 이상이면 호출자 중 하나에서 '타깃 함수 호출 부분과 그 함수로 옮기려는 문장들을 함께' 다른 함수로 추출한다. 추출한 함수에 기억하기 쉬운 임시 이름을 지어준다.
- 다른 호출자 모두가 방금 추출한 함수를 사용하도록 수정한다. 하나씩 수정할 때마다 테스트한다.
- 모든 호출자가 새로운 함수를 사용하게 되면 원래 함수를 새로운 함수 안으로 인라인한 후 원래함수를 제거한다.
- 새로운 함수의 이름을 원래 함수의 이름으로 바꿔준다.
절차
- 호출자가 한두개 뿐이고 피호출 함수도 간단하고 단순한 상황이면, 피호출 함수의 처음줄을 잘라내어 호출자들로 복사해 넣는다. 테스트만 통과하면 이번 리팩터링은 여기서 끝이다.
- 더 복잡한 상황에서는, 이동하지 않길 원하는 모든 문장을 함수로 추출한 다음 검색하기 쉬운 임시 이름을 지어준다.
- 원래 함수를 인라인한다.
- 추출된 함수의 이름을 원래 함수의 이름으로 변경한다.
절차
- 인라인 코드를 함수 호출로 대체한다.
- 테스트한다.
절차
- 코드 조각을 이동할 목표 위치를 찾는다. 코드 조각의 원래 위치와 목표 위치 사이의 코드를 훑어보면서, 조각을 모으고 나면 동작이 달라지는 코드가 있는지 살핀다. 다음과 같은 간섭이 있다면 이 리팩터링을 포기한다.
- 코드 조각에서 참조하는 요소를 선언하는 문장 아픙로는 이동할 수 없다.
- 코드 조각을 참조하는 요소의 뒤로는 이동할 수 없다.
- 코드 조각에서 참조하는 요소를 수정하는 문장을 건너뛰어 이동할 수 없다.
- 코드 조각이 수정하느 ㄴ요소를 참조하는 요소를 건너뛰어 이동할 수 없다.
- 코드 조각을 원래 위치에서 잘라내어 목표 위치에 붙혀 넣는다.
- 테스트한다.
절차
- 반복문을 복제해 두 개로 만든다.
- 반복문이 중복되어 생기는 부수효과를 파악해서 제거한다.
- 테스트한다.
- 완료됐으면, 각 반복문을 함수로 추출할지 고민해본다.
절차
- 반복문에서 사용하는 컬렉션을 가리키는 변수를 하나 만든다.
- 반복문의 첫 줄부터 시작해서, 각각의 단위 행위를 적절한 컬렉션 파이프라인 연산으로 대체한다. 이때 컬렉션 파이프라인 연산은 1.에서 만든 반복문 컬렉션 변수에서 시작하여, 이전 연산의 결과를 기초로 연쇄적으로 수행된다. 하나를 대체할 때마다 테스트한다.
- 반복문의 모든 동작을 대체했다면 반복문 자체를 지운다.
절차
- 죽은 코드를 외부에서 참조할 수 있는 경우라면 혹시라도 호출하는 곳이 있는지 확인한다.
- 없다면 죽은 코드를 제거한다.
- 테스트한다.
출처
리팩터링 2판