SWE

함수의 여러 원칙들

백명석 님의 클린 코더스 강의를 듣고 요약정리한 글입니다. 문제가 있을 경우 삭제 조치하도록 하겠습니다.

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이다.