호출자가 많거나 복잡한 상황에서는, 이동하지 않을 코드를 함수로 추출한 후 임시 이름으로 적용
호출자 코드에 있던 원래 함수 인라인
원래 함수 삭제
추출된 함수의 이름 수정
인라인 코드를 함수 호출로 바뀌기
함수의 이름이 코드의 목적을 말해주므로 코드 이해가 쉬워진다.
함수는 중복을 없애는 데도 효과적
함수 이름이 말이 되지 않는다면 함수 이름이 적절하지 않거나, 그 함수 목적이 인라인 코드의 목적과 다르기 때문일 것이다.
인라인 코드를 대체할 함수를 새로 만들어야 한다면 함수 추출하기를 적용하자.
개요
Before
let appliesToMass = false;
for (const s of states) {
if (s === 'MA') { appliesToMass = true; }
}
After
let appliesToMass = states.includes('MA');
절차
인라인 코드를 함수 호출로 대체
테스트
문장 슬라이드하기
하나의 데이터 구조를 이용하는 문장들은 모여 있어야 좋다.
변수를 처음 사용할 때 선언하는 스타일을 선호
슬라이드할 코드 조각과 건너뛸 코드 중 어느 한쪽이 다른 쪽에서 참조하는 데이터를 수정한다면 슬라이드는 불가하다.
상태 갱신에 신경써야 할 부분이 많으므로 상태 갱신 코드를 최대한 제거하자.
개요
Before
const pricingPlan = retrievePricingPlan();
const order = retrieveOrder();
let charge;
const chargePerUnit = pricingPlan.unit; //이동할 조각 코드
After
const pricingPlan = retrievePricingPlan();
const chargePerUnit = pricingPlan.unit;
const order = retrieveOrder();
let charge;
절차
코드 조각을 이동할 목표 위치 찾기
조각을 모으고 나면 동작이 달라지는 코드가 있는지 살피자.
아래와 같은 간섭이 있다면 이 리팩터링을 포기하자..
코드 조각에서 참조하는 요소를 선언하는 문장 앞으로 이동 불가
코드 조각을 참조하는 요소 뒤로 이동 불가
코드 조각에서 참조하는 요소를 수정하는 문장을 건너뛰어 이동 불가
코드 조각이 수정하는 요소를 참조하는 요소를 건너뛰어 이동 불가
코드 조각을 원래 위치에서 잘라내어 목표 위치에 붙여 넣자
테스트
반복문 쪼개기
하나의 반복문이 두 가지 일을 수행한다면, 각각의 반복문으로 분리하여 수정할 동작 하나만 이해하도록 해보자.
최적화는 리팩터링을 마친 이후에 수행하자
개요
Before
let averageAge = 0;
let totalSalary = 0;
for (const p of people) {
averageAge += p.age;
totalSalary += p.salary;
}
averageAge = averageAge / people.length;
After
let totalSalary = 0;
for (const p of people) {
totalSalary += p.salary;
}
let averageAge = 0;
for (const p of people) {
averageAge += p.age;
}
averageAge = averageAge / people.length;
절차
반복문을 복제해 두 개로 만들기
반복문이 중복되서 생기는 사이드 이펙트를 파악해 제거
테스트
각 반복문을 함수로 추출할지 고민해보기
Example
함수 추출과 반복문 파이프라인으로 바꾸기를 적용하면 더 좋겠다.
function totalSalary() {
return people.reduce((total, p) => total + p.salary, 0);
}
function youngestAge() {
return Math.min(...people.map((p) => p.age));
}
function example() {
return `최연소: ${youngestAge()}, 총 급여: ${totalSalary()}`;
}
반복문을 파이프라인으로 바꾸기
객체가 파이프라인을 따라 흐르며 어떻게 처리되는지를 읽을 수 있다.
filter는 함수를 사용해 입력 컬렉션을 필터링해 부분집합을 만들고, map은 또 다른 함수를 사용해 입력 컬렉션의 각 원소를 변환한다.
개요
Before
function acquireData(input) {
const lines = input.split('\n');
let firstLine = true;
const result = [];
for (const line of lines) {
if (firstLine) { //.1
firstLine = false;
continue;
}
if (line.trim() === '') { //.2
continue;
}
const record = line.split(','); //.3
if (record[1].trim() === 'India') { //.4
result.push({ city: record[0].trim(), phone: record[2].trim() }); //.5
}
}
return result;
}