: 가장 기본적이고, 제일 많이 사용되는 리팩터링 기법들.
1. 함수 추출하기
- 무슨 일을 하는지 파악이 어렵다고 판단된다면 함수로 추출하고, 무슨 일을 수행하는지 적절히 네이밍한다.
- 값을 변경하는 경우 값을 반환하도록 하거나 적절히 문장 슬라이드 등을 이용해본다.
- Call stack과 같은 성능적인 부분을 생각하지 않는다. 오히려 함수가 짧아질수록 캐싱이 더 쉬워져서 컴파일러가 최적화하는데 유리할 때가 많다고 한다.
2. 함수 인라인하기
: 함수 본문이 추출한 네이밍만큼 명확한 경우 그냥 인라인한다. 인라인이 불가능한지를 판단해보고 해야한다.(슈퍼 클래스의 경우 등)
3. 변수 추출하기
: (표현식에 이름을 붙인다) 표현식이 너무 복잡해 로직을 한번에 이해하기 어려운 경우 표현식을 변수로 추출해 쪼개면 관리하기도, 이해하기도 편해진다.
4. 변수 인라인하기
: 변수명이 원래의 표현식과 크게 다를바 없는 경우 인라인한다.
5. 함수 선언 바꾸기
- 함수 네이밍, 시그니처 변경 등이 있다.
- 함수는 시스템의 구성 요소를 조립하는 연결부 역할을 한다. 함수를 잘 정의할수록 시스템 변경이 수월해진다.
- 간단한 절차: 함수 시그니처를 변경하고 사용하는 곳을 적절히 변경한다.
- 마이그레이션 절차: 변경하고자 하는 함수를 새롭게 정의하고 원래의 함수 내에서 새 함수를 호출하도록 구현한 뒤, 해당 함수를 인라인하는 과정으로 리팩터링
- 외부에서 사용되는 경우: versioning을 통해 하위호환을 지원한다. 새로운 버전의 함수를 만들고, 기존의 것을 deprecated 시킨 뒤 모든 클라이언트가 새 버전을 사용한다고 확신이 될 때 deprecated를 삭제한다.
6. 변수 캡슐화하기
- 함수를 사용하면 데이터를 직접 다루기보다, 대체로 호출할 수 있게 된다. 데이터에 접근하는 하나의 통로로 더 데이터를 다루리가 쉬워진다. 캡슐화가 좋은 이유가 이런 이유이다.
- 데이터로 그냥 다루면 (특히 전역 데이터와 같이 데이터 유효범위가 넓은 경우) 해당 데이터를 참조하는 모든 부분을 신경써야한다.
7. 변수 이름 바꾸기
: 변수 이름은 항상 잘 지어야한다.
8. 매개변수 객체 만들기
: 일종의 DTO를 만드는 것. 데이터 항목 여러개가 항상 같이 붙어다니는 경우, 이 데이터들을 객체로 만들고 데이터에 공통으로 적용되는 동작들을 추출해 이 클래스의 메서드로 만들어주면 추상화 관점에서도 좋다.
9. 여러 함수를 클래스로 묶기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Before
function foo1(bar) {
// ..
}
function foo2(bar) {
// ..
}
function foo3(bar) {
// ..
}
// ----
// After
class Foo {
foo1() {
// ..
}
foo2() {
// ..
}
foo3() {
// ..
}
}
- 해당 함수들이 공유하는 공통환경을 더 명확히 표현할 수 있고, 클래스와 관련한 연산들을 해당 클래스의 새로운 메서드로 뽑아낼 수도 있다.
10. 여러 함수를 변환 함수로 묶기
: 데이터를 전달받아 도출하는 로직을 변환 함수로 만들어둔다면 도출 로직의 중복을 줄일 수 있다. 단, 데이터가 변경되는 경우라면 클래스로 분리해주는게 좋다.
11. 단계 쪼개기
- 두 대상을 다루는 모듈을 두가지 모듈로 나누어 한 모듈은 다른 모듈의 상세 내용을 기억하지 않아도 되도록 나눈다.
- 컴파일러는 컴파일을 하기 위해 텍스트 토큰화, 구문트리 만들기 등의 단계를 통해 실행 가능한 형태로 컴파일한다.
Reference)
리팩터링 2판