백명석 님의 클린 코더스 강의를 듣고 요약정리한 글입니다. 문제가 있을 경우 삭제 조치하도록 하겠습니다.
1. Function의 원칙
- 한 가지 일만 해야 한다.
- 함수의 크기는 화면에 보이는 양보다 훨씬 작아야 한다. (smaller than a screenful), 극단적이지만 4줄짜리 함수여야 한다고 주장하기도 한다. (이번 우아한테크코스 4주 차 미션 컨벤션에서는 10줄 미만이다.)
- indentation, while, nested if등은 없어야 한다.
- 잘 지어진 서술적인 긴 이름을 갖는 많은/작은 함수들로 유지해야 한다. (small many functions, nice descriptive long name)
2. The First Rule of Functions
- 더 이상 작아질 수 없을 만큼 작아야 한다.
- 큰 함수를 보면 클래스로 추출할 생각을 해야한다. (Extract Method Object 기법, 큰 함수를 새로운 오브젝트로 추출)
- 클래스는 일련의 변수들에 동작하는 기능의 집합이다. (큰 함수도 파라미터와 그 함수 내의 지역변수들에 동작하는 기능들의 집합이다. 즉, 클래스로 추출할 수 있다.)
3. Function Refactoring
주의, 메서드와 함수를 혼용해서 사용합니다. 직접 실습은 이곳 에서 진행할 수 있습니다.
개선 방법
- 큰 함수는 클래스로 분리할 수 있다.
- 메서드의 여러 곳에서 사용되는 변수들은 큰 메서드를 작은 메서드로 분리할 때 인자로 사용되어 불편하기 때문에 필드로 올려 인자의 개수를 줄인다. (특히, 한 메서드에서 2개 이상의 변수를 변경하는 경우, 필드로 추출하지 않으면 추출이 불가능하다.)
- 리팩토링 이후에는 반드시 테스트를 수행하면서 안전 여부를 확인한다.
- 여러 부분에 걸쳐 공통의 메서드 추출할 때, 서로 다른 점은 변수로 추출한다. 이후에 추출된 메서드의 인자로 변수를 전달한다.
- 다른 부분을 파라미터로 처리하기 위해서 추출했던 변수들을 인라인 하여 코드를 깨끗하게 한다.
- 밥 아저씨는 괄호가 있으면, 한 가지 이상의 일을 하는 경우이다. 혹은 그런 징조라 말했다.
- 조건문의 복잡한 식을 메서드로 추출할 수 있다.
- 의미 있는 이름으로 클래스와 메서드 이름을 변경한다.
개선
- 읽기 쉬워졌다.
- 이해하기 쉬워졌다.
- 함수가 자신의 의도를 잘 전달한다.
개선의 원인
- Small (함수의 첫 번째 규칙, 함수는 작아질 수 있는 한 최대한 작아야 한다.)
- 블록이 적어야 한다. (if, else, while 문장 등의 내부 블록은 한 줄이어야 한다. 즉 괄호가 없어야 하고, 함수 호출이어야 한다.)
- Indenting이 적어야 한다. (함수는 중첩 구조를 가질 만큼 크면 안 된다. 들여 쓰기는 한두 단계 정도만 허용한다.)
4. functions should do one thing
리팩토링 이전의 함수들은 하나 이상의 일을 한다. 리팩토링을 하고 나서, 함수들은 한 가지 단순한 일만 수행해야 한다.
- 함수가 수행하는 모든 일의 추상화 수준이 같다.(All At Same Level..)
- 함수의 각 스텝들은 함수 이름보다 한수준 낮은 추상화 수준을 갖는다.
- 함수의 각 스텝들이 함수 이름이 갖는 추상화 수준보다 한 단계 낮은 것으로만 이뤄졌다면 함수는 한 가지 일만 하는 것이다. (즉, 함수를 구성하는 여러 스텝이 같은 추상화 수준이라면, 그 함수는 한가지 일을 한다고 표현할 수 있다.)
- 원래 코드는 추상화 수준이 다른 많은 단계들을 포함하므로 한 가지 이상의 일을 한다는 것이 명확하다.
- 함수가 하나 이상의 일을 한다고 말할 수 있는 경우는 단순한 구현의 재인용이 아닌 이름으로 함수를 추출할 수 있을 때이다. (즉, 추상화 수준이 변하지 않고, 재인용이라고 생각이 될 때까지, 잘 지어진 이름을 가진 메서드 추출을 하면 성공!)
추상화 수준이란?
(개인적인 생각으로 목표라고 생각해도 될 듯하다.)
상위 레벨 추상화: to RenderPageWithSetupAndTeardowns we
- 페이지가 테스트 페이지인지 결정
- 테스트 페이지인 경우, setups, teardowns를 include
- HTML로 페이지를 렌더링
이를 테면, 어느 메서드는 위와 같은 동작(스텝)을 포함한다. 같은 추상화 단계의 여러 스텝들이기 때문에 그 메서드는 한 가지일을 수행한다고 볼 수 있다. (같은 추상화 수준)
5. Where do classes go to hide?
- 큰 함수는 실제로는 클래스가 숨어있는 곳이다.
- 큰 함수는 변수와 인자들이 들여 쓰기에 존재하며, 변수들을 사용해서 통신하는 기능들의 집합이다. 이를 항상 하나 이상의 클래스로 분리할 수 있다.
6. One thing???
function should do one things, do it well, do it only
함수는 한 가지 일만 해야 하고, 한 가지만 하는지 확신할 수 있는 유일한 방법은 extract till you drop이다. 하나 이상의 섹션으로 구성된 함수는 적어도 reader 입장에서는 one thing을 하는 것이 아니다.
큰 함수를 작은 함수들로 쪼갤 때 흥미로운 일을 수행
- 주요 섹션을 함수로 추출
- 서로 다른 추상화 레벨로 분리
- 함수가 하나 이상의 추상화 레벨을 다루면 이 함수는 한 가지 이상의 일을 하는 것
Extract Till you drop
- 더 이상 extract 할 수 없을 때까지 extract하라.
- extract할 코드를 가진 함수는 한 가지 이상의 일을 하는 것이다.
- 4줄 이내의 함수로만 구성된 클래스
- if, while 문 등에서 {}가 보이면 extract 대상
- {}는 extract할 기회
7. 결론
- 1st rule : function should be small
- 2nd rule: smaller then that
- 이름을 잘 지으면 당신뿐 아니라 모든 사람들의 시간을 절약해준다.
- 함수를 작게 만들면 모두의 시간을 절약할 수 있다.
- 클래스는 큰 함수를 감춘다.
- 함수는 한 가지 일만 해야 하고, 한 가지만 하는지 확신할 수 있는 유일한 방법은 extract till you drop이다.