변수 추출하기(Extract), 인라인하기(Inline), 선언바꾸기(change)
리팩토링 173p ~ 187p
변수 추출하기
return 값으로 이렇게 복잡하게 변수로만 되어있다면 이 변수가 무엇을 계산해서 반환하는지 하나씩 다 뜯어봐야한다.
return order.quantity * order.itemPrice -
Math.max(0, order.quantity - 500) * order.itemPrice * 0.05
+ Math.min(order.quantity * order.itemPrice * 0.1, 100);
하지만 아래와 같이 변수로 추출해서 반환한다면 리턴값으로 변수명들만 봐도 어떻게 계산되는 코드를 하나씩 듣어보지 않아도 되게 된다.
const basePrice = order.quantity * order.itemPrice;
const quantityDiscount = Math.max(0, order.quantity - 500) * order.itemPrice * 0.05;
const shipping = Math.min(order.quantity * order.itemPrice * 0.01, 100);
return basePrice - quantityDiscount + shipping;
표현식이 너무 복잡할 때는 지역변수를 활용하면 표현식을 쪼개 관리하기 더 쉽게 만들 수 있다. 그러면 복잡한 로직을 구성하는 단계마다 이름을 붙일 수 있어서 코드의 목적을 훨씬 명확하게 드러낼 수 있다.
즉, 변수 추출을 고려한다고 함은 표현식에 이름을 붙이고 싶다는 뜻이다. 이름을 붙이기로 했다면 그 이름이 들어갈 문맥도 살펴야 한다.
절차
1. 추출하려는 표현식에 부작용은 없는지 확인한다.
2. 불변 변수를 하나 선언하고 이름을 붙일 표현식의 복제본을 대입한다.
3. 원본 표현식을 새로 만든 변수로 교체한다.
4. 테스트한다.
5. 표현식을 여러 곳에서 사용한다면 각각을 새로 만든 변수로 교체한다. 하나 교체할 때마다 테스트한다.
변수 인라인하기
변수는 함수 안에서 표현식을 가리키는 이름으로 쓰이며, 대체로 긍정적인 효과를 준다. 하지만 그 이름이 원래 표현식과 다를 바 없을 때도 있다. 또 변수가 주변 코드를 리팩터링하는데 방해가 되기도 한다. 이럴 때는 그 변수를 인라인 하는 것이 좋다.
// 1번
let basePrice = anOrder.basePrice;
return (basePrice > 1000);
//-------------------------------
// 2번
return anOrder.basePrice > 1000;
절차
1. 대입문의 우변(표현식)에서 부작용이 생기지 않는지 확인한다.
2. 변수가 불변으로 선언되지 않았다면 불변으로 만든 후 테스트한다.
3. 이 변수를 가장 처음 사용하는 코드를 찾아서 대입문 우변의 코드로 바꾼다.
4. 테스트한다.
5. 변수를 사용하는 부분을 모두 교체할 때까지 이 과정을 반복한다.
6. 변수 선언문과 대입문을 지운다.
7. 테스트한다.
함수 선언 바꾸기
함수는 프로그램을 작은 부분으로 나누는 주된 수단이다.
이름이 좋으면 함수의 구현 코드를 살펴볼 필요 없이 호출문만 보고도 무슨 일을 하는지 파악할 수 있다.
하지만 고작 이름일 뿐이라고 생각할 수 있지만, 나중에 그 코드를 볼 때 무슨일을 하는지 '또' 고민하는 일을 피할 수 있게 된다.
처음에 어렵다면 주속을 이용해 함수의 목적을 설명해보고, 그것을 토대로 이름을 짓는것도 좋은 방법이다
아래 예시는 함수이름을 너무 축약시켜서 circumference 원의 둘레라는 뜻으로 바꿔줬다.
function circum(radius) {...}
// --------------------------
function circumference(radius) {...}
절차
이 단계에서 리팩터링을 할 때는 먼저 변경 사항을 살펴보고 함수 선언과 호출문들을 단번에 고칠 수 있는지 가늠해봐야한다. 가능할 것 같다면 간단한 절차를 따르고, 그렇지 않다면 마이그레이션 절차를 적용해 호출문들을 점진적으로 수정할 수 있다.
간단한절차
1. 매개변수를 제거하려거든 먼저 함수 본문에서 제거 대상 매개변수를 참조하는 곳은 없는지 확인한다.
2. 메서드 선언을 원하는 형태로 바꾼다.
3. 기존 메서드 선언을 참조하는 부분을 모두 찾아서 바뀐 형태로 수정한다.
4. 테스트한다.
마이그레이션절차
1. 이어지는 추출 단계를 수월하게 만들어야 한다면 함수의 본문을 적절히 리팩터링한다.
2. 함수 본문을 새로운 함수로 추출한다.
3. 추출한 함수에 매개변수를 추가해야 한다면 '간단한 절차'를 따라 추가한다.
4. 테스트한다.
5. 기존 함수를 인라인한다.
6. 이름을 임시로 붙여줬다면 함수 선언 바꾸기를 한 번 더 적용해서 원래 이름으로 되돌린다.
7. 테스트한다.