본 내용은 마틴 파울러의 Refactoring 2판을 토대로 작성되었습니다.
리팩터링: 첫 번째 예시
임의 변수를 질의 함수로 바꾸기
- 임시 변수들 때문에 로컬 범위에 존재하는 이름이 늘어나서 추출 작업이 복잡해 짐
- 임시 변수는 자신이 속한 함수에서만 의미가 있음
- 이러한 변수들을 함수로 추출
- 임시 변수를 제거해서 얻는 가장 큰 장점은 추출 작업이 훨씬 쉬워짐
- 유효범위를 신경 써야 할 대상이 줄어들기 때문
- 이후 해당 변수가 사용되던 부분은 변수 인라인하기
리팩터링과 성능
- 리팩토링을 하면서, 데이터 조회를 더 하게 되거나 반복문이 늘어날 수도 있음
- 대부분의 경우에는 성능에 큰 영향은 없음
- 설사 느려지더라도, 제대로 리팩터링된 코드베이스는 그렇지 않은 코드보다 성능을 개선하기 훨씬 수월
- 반복문을 쪼개는 경우, 성능에 미치는 영향이 미미
- 컴파일러들은 최신 캐시 기법 등으로 무장
- 소프트웨어 성능은 대체로 코드의 몇몇 작은 부분에 의해 결정되므로 그 외의 부분은 수정하여도 성능 차이를 체감할 수 없음
문장 슬라이드
- 변수 초기화 문장을 변수 값 누적 코드 바로 앞으로 옮김
- 해당 변수의 의미와 용도를 명시적으로 알 수 있음
로직 분리하기
- 복잡한 코드를 잘게 쪼개는 것은 중요
- 로직을 적절한 기준으로 단계 쪼개기
- 유지, 보수 및 기능 추가하기 수월해 짐
가변 데이터
- 객체와 같은 가변 데이터는 예상치 못하게 수정되는 문제가 발생할 수도 있음
- Object.assign 과 같은 메서드를 사용하여, 얕은 복사를 수행
- 가변 데이터를 최대한 불변 데이터와 같이 취급
다형성을 활용한 코드 재구성
- 조건부 로직은 코드 수정 횟수가 늘어날수록 골칫거리가 됨
- 프로그래밍 언어가 제공하는 구조적인 요소로 적절히 보완
- 객체지향의 핵심 특성인 다형성을 활용하는 것이 자연스러움
- JavaScript는 ECMAScript 2015(ES6)부터 객체지향을 사용할 수 있는 문법과 구조가 지원
- 조건부 로직 -> 다형성으로 바꾸기
- 일반적인 경우를 기본으로 삼아 슈퍼클래스에 남기고, 달라지는 부분은 필요할 때 오버라이드하게 만드는 것이 좋음
생성자 팩터리 함수
- JavaScript에서는 생성자가 서브클래스의 인스턴스를 반환할 수 없음
- 생성자를 팩터리 함수로 바꾸기를 적용
function createPerformencCalculator(aPerformance, aPlay) {
switch(aplay.type) {
case "treagedy": return new TragedyCalculator(aPerformance, aPlay);
case "comedy": return new ComedyCalculator(aPerformance, aPlay);
default:
throw new Error(`알 수 없는 장르: ${aPlay.type}`);
}
}
이번장 정리
- 리팩터링을 크게 세 단계로 진행
- 원본 함수를 중첩 함수 여러개로 나누기
- 단계 쪼개기를 적용하여 로직을 분리
- 조건부 로직을 다형성으로 표현
- 좋은 코드를 가늠하는 핵심은 '얼마나 수정하기 쉬운가'다