함수는 프로그램의 가장 기본적인 단위이다.
작게 만들어라
모두가 함수를 작게 만들어야 한다고 말한다. 어떻게 함수를 작게 만들어야 할까?
✅ if, else 문/ while 문 등에 들어가는 블록은 한 줄이어야 한다. ➡️ 거기서 함수를 호출
한 가지만 해라!
함수가 한 가지 작업만 하는지 확인하려면 아래 조건을 확인해야 한다.
- 추상화 수준이 하나인 단계만 수행한다.
- 단순히 다른 표현이 아니라 의미 있는 이름으로 다른 함수를 추출할 수 없다.
추상화 수준이란 정확히 무슨 의미일까?
추상화 수준
추상화 수준은 "코드가 '무엇'을 하는지와 '어떻게' 하는지를 구분하는 단계"라고 생각한다.

함수1, 함수2는 코드가 "무엇"을 하는지 나타내고, 함수1-1, 함수1-2, 함수1-3은 함수1이 "어떻게" 실행되는지를 나타낸다.
함수1-1, 함수1-2, 함수1-3 역시 더 낮은 추상화 수준 함수에겐 "무엇"을 하는지를 나타낼 것이다.
위에서 아래로 코드 읽기: 내려가기 규칙
추상화 수준이 높은 함수에서 시작해서, 추상화 수준이 낮은 함수로 코드를 작성한다.
추상화 수준이 높은 함수에서 여러 추상화 수준이 낮은 함수가 호출된다면,
- 제일 먼저 나온 추상화 수준이 낮은 함수
- 그 다음 나온 추상화 수준이 낮은 함수
- ...
순서로 코드를 작성하고, 1번 함수에서 파생하는 모든 함수를 다 작성하고 2번 함수를 작성하자.
Switch 문
swtich문은 N가지 일을 처리하기 때문에 '한 가지' 작업만 하기 어렵다.
swtich문을 사용할 땐, 다형적 객체를 생성하는 코드 안에서 사용하자. (factory 패턴을 고려하자.)
서술적인 이름을 사용하라
길고 서술적인 이름이 짧고 어려운 이름보다 좋다.
길고 서술적인 이름이 길고 서술적인 주석보다 좋다.
💡중요한 것은, 모듈 내에 일관성있는 작명을 하고 짐작한 대로 함수가 작동해야 한다.
함수 인수
함수의 인수는 적을 수록 좋다. (테스트 관점에서 보면 더욱 그렇다.)
특히, 출력 인수는 우리가 알고 있는 기본적인 개념(함수에 인수를 넣고 반환값을 출력 받는 개념)과 달리 인수로 결과를 받는다. 이는 독자로 하여금 혼란을 일으킨다.
출력 인수는 되도록 피하자. ➡️ this를 사용하라.
단항 형식
아래 3가지 경우가 아니면 단항 함수는 가급적 피하자.
- 인수에 질문을 던지는 경우
- 인수를 뭔가로 변환해 결과를 반환하는 경우 ➡️ 입력 인수를 그대로 돌려주는 함수라도 변환 함수 형식을 따르는 편이 좋다.
- 이벤트
1번이 명확하게 다가오지 않을 수 있다.
// 1번의 예시
public class Order {
public boolean isQuantityValid(int quantity) {
return quantity > 0;
}
public void process(int quantity) {
if (isQuantityValid(quantity)) { // 인수에 대해 질문
// 처리 로직
}
}
}
isQuantityValid(quantity)함수의 작업은 quantity 인수에 질문을 던져 상태를 반환한다.
💡 단항 함수는 함수와 인수가 동사/명사 쌍을 이뤄서 작명하자. ex) write(name): '이름'이 무엇이든 '쓴다'는 뜻
이항 함수
인수 2개가 한 개념을 표현하는 경우에 사용하기 좋다. 그렇지 않으면 가능한 단항 함수로 바꾸도록 애쓰자.
삼항 함수
인수가 3개인 함수는 이해하기 어렵다. 삼항 함수를 만들 때는 신중히 고려하자.
인수 객체
객체를 생성해 인수를 줄이는 방법이 있다. 객체는 곧 개념이기 때문에 실제론 좋은 방법이다.
명령과 조회를 분리하라!
함수의 종류
- 객체 상태를 변경(명령)
- 객체 정보를 반환(조회)
오류 코드보다 예외를 사용하라!
명령 함수에서 오류 코드를 반환한다면, 이때 조회가 있기 때문에 명령/조회 분리 규칙을 위반한다.
오류 코드가 변하면 해당 오류 코드를 사용하는 클래스 전부를 다시 컴파일하고 다시 배치해야 한다.
이를 해결하기 위해선 try/catch 블록을 통해 예외를 사용하자.
💡오류 처리도 '한 가지' 작업이다.
나머지
중복된 코드는 묶어라.
큰 함수에서 return 문이 하나여야 하고, break, continue, goto를 사용하지 말자.
작은 함수에선 간혹 return, break, continue를 여러 차례 사용해도 좋다.
💡큰 함수는 여러 일을 하는 함수, 작은 함수는 한 가지 일을 하는 함수라고 생각한다.
함수 내용이 합리적인지 합리적인지 합리적인지 의심해라.
'Clean Code' 카테고리의 다른 글
| [Day 6] 경계 (1) | 2024.10.29 |
|---|---|
| [Day 5] 오류 처리 (0) | 2024.10.29 |
| [Day 4] 객체와 자료 구조 (1) | 2024.10.25 |
| [Day 3] 형식 맞추기 (0) | 2024.10.24 |
| [Day 1] 의미 있는 이름 (3) | 2024.10.22 |