파이브 라인스 오브 코드
3장. 긴 코드 조각 내기
DRY 및 KISS 지침들이 어려웠던 이유
DRY: Don't Repeat Yourself (반복하지 말라는 뜻)
KISS: Keep It Simple Stupid (단순하게 만들라는 뜻)
- 메서드가 여러가지 다른 일을 수행한다.
- 낮은 수준의 원시 연산을 사용한다.
- 주석과 적절한 메서드와 변수명 같이 사람이 읽을 수 있는 텍스트가 부족하다
왜 다섯줄인가?
-
메서드는
{
와}
를 제외하고 5줄 이상이 되어서는 안된다. -
모든 메서드를 이 규칙을 준수하도록 바꿀 수 있다.
-
스멜
- 메서드가 길다는 것 자체가 냄새가 나는 것이다.
- 긴 메서드의 모든 논리를 머릿속에 담아야해서 작업하기 어렵다.
-
의도
- 시간이 지남에 따라 추가되는 기능들로 인해 메서드가 커지는 경향이 있다.
- 5줄의 코드가 있는 4개의 메서드가 20줄인 하나의 메서드보다 훨씬 빠르고 이해하기 쉽다.
-
코드를 이해하기 위한 첫번재 단계는 항상 함수명을 고려하는 것
리팩터링: 메서드 추출
메서드를 더 작은 조각으로 분해하는 리팩터링 기법이다.
-
원하는 이름으로 새로운 빈 메서드 생성
-
그룹의 맨 위에서 새로운 메서드 호출
-
그룹의 코드를 잘라내어 새로운 메서드의 본문에 붙여넣기
-
컴파일
-
매개변수를 도입하여 호출하는 쪽의 오류를 발생시키기
-
매개변수 중 하나를 반환 값으로 할당해야하는 경우
- 새로운 메서드의 마지막에 반환값을 추가
- 새로운 메서드를 호출하는 쪽에서 반환값을 할당
-
컴파일
-
호출 쪽 인자 설정
-
사용하지 않는 코드와 주석 제거
- 이 절차는 아무것도 손상시키지 않는다.
- 코드가 수행하는 작업을 아직 살펴보지 않는 경우에는 아무것도 고장내지 않았다는 확신이 가장 중요함
규칙: 호출 또는 전달, 한가지만 할 것
- 함수 내에서는 객체에 있는 메서드를 호출하거나 객체를 인자로 전달할 수 있지만 둘을 섞어 사용해서는 안됨
- 많은 메서드 및 여러가지 매개변수를 전달하는 경우, 결국 해당 함수의 책임이 고르지 않게 됨
function average(arr: number[]) {
return sum(arr) / arr.length
}
function average(arr: number[]) {
return sum(arr) / size(arr)
}
- 위 함수는 높은 수준의 추상화와 낮은 수준의
arr.length
를 모두 사용 - 스멜
- 함수의 내용은 동일한 추상화에 이썽야한다.
- 전달된 인자의 메서드가 어떻게 사용되는지 식별하는 방법은 인자로 전달된 변수 옆의
.
을 통해 찾을 수 있다.
- 의도
- 메서드에서 몇가지 세부적인 부분을 추출해서 추상화를 도입할 때 연관된 다른 세부적인 부분도 추출하게 한다.
- 이러면 메서드 내부의 추상화 수준이 동일하게 유지
좋은 함수의 이름의 속성
- 정직해야한다
- 함수의 의도를 설명해야한다
- 완전해야한다
- 함수가 하는 모든 것을 담아야한다
- 도메인에서 일하는 사람이 이해할 . 수있어야한다.
- 함수명을 지을 떄는 항상 나중에 함수가 더 작아졌을 때, 이름을 개선할 수 있는지를 평가해야한다.
규칙: if문은 함수의 시작에만 배치
- if문이 있는 경우, 해당 if문은 함수의 첫번째 항목이어야한다.
- 함수는 한가지 일만 해야한다
- 무언가를 확인하는 것은 한가지 일 즉 if 가 있는 경우 함수의 첫번째 항목이어야 하고, 그 후에는 아무것도 해서는 안된다.
- if 문을 분리하가 위해 메서드 추출을 사용한다.
function reportPrimes(n: number) {
for (let i = 2; i < n; i++) {
if (isPrime(i)) {
console.log(`${i} is prime`);
}
}
}
function reportPrimes(n: number) {
for (let i = 2; i < n; i++) {
reportIfPrime(i);
}
}
function reportIfPrime(n: number) {
if (isPrime(i)) {
console.log(`${i} is prime`);
}
}
-
스멜
- 다섯 줄 제한과 같이 이 규칙은 함수가 한가지 이상의 작업을 수행하는 스멜을 막기 위해 존재
-
의도
- if 문이 하나의 작업이기 때문에 이를 분리할 때 이어지는 else if 는 if 문과 분리할 수 없는 원자 단위로 봄