함수는 프로그램의 가장 기본적인 단위이다.
읽기 쉬운 함수를 만드는 방법을 설명한다.
하나의 함수 안에 들어가는 코드 수를 너무 많게 하면 안된다.
함수 하나에 하나의 이야기를 표현한다.
if문/else문/while문에 들어가는 블록은 한 줄로 한다.
이 한 줄에서 함수를 선언하게 된다.
하나의 함수 안에서는 한 가지 기능만 해야 한다.
한 가지 기능만 하는 함수는 섹션으로 나누기 어렵다.
switch문은 한가지의 작업을 처리하지 않고, 여러개의 작업을 처리한다. 따라서 작게 만들기 어렵다.
다형성 객체를 생성하는 코드 안에서 switch 문을 한 번 정도는 사용해도 된다.
함수의 이름은 함수가 하는 일을 가장 잘 설명할 수 있는 서술적 이름으로 정해야 한다. 함수의 기능이 단순할수록 서술적인 이름을 정하기 쉬워진다. 길더라도 서술적인 이름이 서술적인 주석보다 낫다.
함수의 인수 개수는 0개가 가장 이상적이다. 인수는 적을수록 좋다. 4개 이상은 사용해서는 안된다.
함수를 읽는 사람에게 인수는 이해하기 어렵다. 인수가 많아지면 테스트 케이스가 많아져 테스트가 복잡해진다.
함수에 인수 1개를 넘기는 이유
인수에 질문을 던지는 경우
: ex) boolean fileExists("MyFile")
파일이 존재하는지 확인한다.
인수를 무언가로 변환해 결과를 반환하는 경우
: ex) InputStream fileOpen("MyFile")
String 형식의 파일 이름을 InputStream 형식으로 변환한다.
이벤트 함수인 경우
: 입력 인수만 있고, 출력 인수는 없다.
함수의 인자로 부울 값을 넘긴다는 것은 함수가 여러가지 기능을 한다는 것을 의미하기 때문에 최악이다.
인수가 많아질수록 함수를 이해하기 힘들다. 가능하면 단항 함수로 바꾸도록 해야 한다.
단항, 이항 함수보다 이해하기 힘들다. 삼항 함수를 만들 때는 신중히 만들어야 한다.
인수의 수가 너무 많아지면, 객체로 묶어서 보낸다.
객체로 묶으면 이름을 붙이면서 설명을 붙이게 되기 때문에 적절하다.
인수의 개수가 바뀔 수 있는 가변적인 함수도 존재한다.
부수 효과 : 함수 내의 실행으로 인해 함수 외부가 영향을 받는 것
함수가 한 가지 기능을 한다고 하고, 함수 외부에서 변화를 알아채지 못하는 일이 발생할 수 있다.
꼭 필요한 기능이라면 함수 이름에 명시해야 한다.
함수는 명령을 수행하거나 원하는 것을 찾는 조회 기능을 함께 수행해서는 안된다. 한 기능만 수행해야 한다.
set("username", "unclebob")
-> 설정을 하는 코드인지, 설정이 되어 있는지 확인하는 코드인지 모호하다.
setAttribute("username", "unclebob")
위의 코드는 모호함을 해결한다.
명령을 수행하는 함수에서 오류 코드를 반환하게 되면 명령과 조회를 분리하라는 규칙을 어기게 된다.
if (deletePage(page) === E_OK)
페이지를 지우는 코드인지, 지워졌는지 확인하는 코드인지 모호해진다.
오류 코드를 반환하면 바로 처리해야 한다.
=> 오류 코드 대신에 예외를 사용하도록 한다.
try/catch 문은 코드 구조에 혼란을 주기 때문에 별도 함수로 뽑는 것이 좋다.
함수는 한가지 작업만 해야 하는 것처럼 오류 처리 함수도 오류 처리 작업만 해야 한다.
-> try로 시작해 catch/finally로 끝나야 한다.
반복되는 알고리즘이 나타나면 include로 중복을 없앤다.
함수의 구조가 클 때는 하나의 return문만 존재해야 한다. break나 continue는 사용하면 안된다. 하지만 함수가 작을 때는 사용해도 괜찮다.
글을 쓰는 것처럼 초안을 쓰고 고쳐나가는 방식으로 함수를 짠다.