목차
- 작게 만들어라!
- 한 가지만 해라!
- 함수 당 추상화 수준은 하나로!
- Switch 문
- 서술적인 이름을 사용하라
- 함수 인수
- 부수 효과를 일으키지 마라!
- 명령과 조회를 분리하라!
- 오류 코드보다 예외를 사용하라!
- 반복하지 마라!
- 구조적 프로그래밍
- 함수를 어떻게 짜죠?
- 결론
작게 만들어라!
작게의 기준은 무엇일까?
- 블록과 들여쓰기
if/else/switch 문 등에 들어가는 블록은 한 줄이며 indent는 2단을 넘어서면 안된다.
적절한 메서드명을 가지는 메서드를 호출하는 방식을 통해 이를 충족시킨다.
한 가지만 해라!
함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다.
함수는 추상화 수준이 하나인 단계만 수행한다면 그 함수는 한 가지 작업만 한다.
한 함수에서 섹션을 나눌 수 없다면 함수가 한 가지 작업을 한다고 할 수 있다.
함수 당 추상화 수준은 하나로!
함수 내에 추상화 수준이 섞이면 특정 표현이 근본 개념인지 세부사항인지 구분하기 어려워진다.
- 위에서 아래로 코드 읽기: 내려가기 규칙
한 함수 다음에는 추상화 수준이 한 단계 낮은 함수가 오면 함수 추상화 수준이 한번에 한 단계씩 낮아진다. 코드는 위에서 아래로 이야기처럼 읽혀야 좋다.
Switch 문
Bad :
public Money calculatePay(Employee e) throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
Switch문의 문제점
- 함수가 길어진다
- '한 가지' 작업만 수행하지 않는다.
- Single Response Principle를 위반한다.
- Open Closed Principle을 위반한다.
Switch문은 다형적 객체를 생성하는 코드안에서만 사용하도록 해야 한다.
서술적인 이름을 사용하라
일관적이고 서술적인 이름을 사용하여 함수 이름만으로 해당 함수가 하는 일을 파악할 수 있도록 해야 한다.
함수 인수
테스트 코드 관점에서도 인자가 많을수록 테스트를 위한 유효한 인자를 만들어야 하는 문제가 생긴다.
가장 이상적인 인수 개수는 0개, 최대 3개. 하지만 적을수록 좋다. 줄이자 줄이자!
- 많이 쓰는 단항 형식
- 인수에 질문을 던지는 경우
- 인수를 뭔가로 변환해 결과를 반환하는 경우
- 이벤트 (출력은 없는 경우, 다소 드물다) - 이름과 문맥을 통해 이벤트 함수임을 명확히 드러내야 한다.
- 플래그 인수
플래그 인수 값에 따라 메서드가 다른 기능을 하게 된다는 의미이므로 플래그 인수는 지양해야 한다. - 이항 함수
무시해도 되는 인자가 있는 순간 버그 확률이 늘어난다.
이항 함수가 적절한 경우는 인수 2개가 한 값을 표현하는 두 요소인 경우, 자연적인 순서가 있는 경우이다.
같은 클래스인 2개의 인자를 받는 경우 순서를 헷갈릴 수 있으므로 지양해야 한다. - 삼항 함수
순서, 주춤, 무시로 야기되는 문제는 두 배 이상으로 늘어난다.
인자의 의미가 명확한 경우가 아니면 지양한다. - 인수 객체
결국 변수에 이름을 붙여야 하므로 개념을 표현하게 되는 것이다.
e.g.,Circle makeCircle(double x, double y, double radius); Circle makeCircle(Point center, double radius);
- 인수 목록
가변 인수 전부가 동등하게 취급될 경우 List 형 인수 하나로 취급할 수 있다.
e.g.,public String format(String format, Object... args)
- 동사와 키워드
함수의 의도나 인수의 순서와 의도를 함수 이름에 담아야 한다.
함수 이름에 인자의 키워드를 추가하여 인자의 의미와 순서를 보장 해 준다.
부수 효과를 일으키지 마라!
함수는 꼭 한 가지 기능만을 한다.
부수 효과로 발생 가능한 문제?
- Temporal Coupling
- Order Dependency
명령과 조회를 분리하라!
함수의 역할
- 뭔가를 수행한다.
- 뭔가에 답한다.
Bad :
// attribute인 속성을 찾아 값을 value로 설정 후 성공시 true, 실패시 false
public boolean set(String attribute, String value);
if (set("username", "unclebob")) ...
Good :
if (attributeExist("username")) {
setAttribute("username", "unclebob");
}
오류 코드보다 예외를 사용하라!
오류코드의 문제점
- 호출자는 오류 코드를 바로 처리해야 한다.
- 의존성 자석 : 오류 코드의 수정/추가/삭제가 일어날 경우 처리 코드도 수정해야 한다
Try/Catch 블록 뽑아내기
오류처리도 한 가지 작업임을 인지하고 오류 처리 함수를 분리하도록 한다.
Bad : try/catch 블록은 정상 동작과 오류 처리 동작을 섞으며 코드 구조에 혼란을 일으킨다.
try {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
logger.log(e.getMessage());
}
Good :
public void delete(Page page) {
try {
deletePageAndAllReferences(page);
} catch (Exception e) {
logError(e);
}
}
// 정상 동작만을 처리한다.
private void deletePageAndAllReferences(Page page) throws Exception {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) {
logger.log(e.getMessage());
}
반복하지 마라!
반복되는 코드가 다른 코드와 섞이면 모양이 달라지면서 중복이 잘 드러나지 않게 되어 수정이 일어날 때 오류가 발생할 확률이 높아진다.
중복을 없애거나 제어 할 목적의 원칙과 기법들
- 관계형 데이터베이스에 정규 형식을 만듦
- 객체지향 프로그래밍 - 코드를 부모 클래스로 몰아 중복을 없앰
- 구조적 프로그래밍
- AOP(Aspect Oriented Programming) - Spring의 핵심 개념 중 하나로 부가기능의 모듈화 (하단 링크들 참고)
- COP(Component Oriented Programming) - 기존 시스템이나 소프트웨어를 구성하는 컴포넌트를 조립해서 하나의 새로운 응용프로그램을 만드는 소프트웨어 개발 방법론
구조적 프로그래밍
모든 함수와 함수 내 모든 블록에 entry와 exit이 하나만 존재해야 한다. 즉, return 문이 하나여야 한다. 루프 안에서 break, continue를 사용해서는 안 되며 goto는 절대로 안된다.
함수가 클 때만 이익을 제공하는 기법이다.
함수가 작을때는 return, break, continue를 여러차례 사용해도 괜찮지만 goto는 작은 함수에서도 피해야 한다.
함수를 어떻게 짜죠?
TDD
테스트 코드 -> 중복, 네이밍, 들여쓰기 등 상관없이 우선 기능을 개발 -> 리팩토링 (무조건 단위테스트는 계속 통과)
위 과정을 반복한다.
결론
위의 규칙들을 잘 따라 시스템을 잘 풀어가야한다!
참고하면 좋을 문서
AOP
'Dev > Books' 카테고리의 다른 글
[CleanCode] 7장. 예외 처리 (0) | 2020.05.16 |
---|---|
[CleanCode] 6장. 객체와 자료 구조 (0) | 2020.05.15 |
[CleanCode] 5장. 형식 맞추기 (0) | 2020.05.12 |
[CleanCode] 4장. 주석 (0) | 2020.05.12 |
[CleanCode] 2장. 의미있는 이름 (0) | 2020.05.02 |