Clean Code를 읽고 정리한 글입니다.
240312. 23:51
함수는 최대한 작게 만들기
함수는 작을 수록 좋다. if, else, while 문에 들어가는 블록은 한 줄이어야 한다는 말이다.
함수에서 한 가지만 처리
한 가지만 처리한다는 말 중에서 한 가지가 어디까지를 뜻하는지 모호할 수 있지만, 추상화 수준이 하나라면, 함수가 한 가지 일을 처리한다고 할 수 있다. 지정된 함수 아래에서 추상화 수준이 한 개인 단계만 수행한다면, 그 함수는 한 가지 작업만 한다고 할 수 있다.
함수당 추상화 수준은 하나로 하기
한 함수 내에 추상화 수준을 섞으면 코드를 읽는 사람이 헷갈린다. 예를 들어서 .append() 의 경우, 추상화의 수준이 아주 낮지만, .render() 와 같은 경우는 추상화가 중간이고, .getHtml() 은 추상화의 수준이 높다.
위에서 아래로 코드 읽기 : 내려가기 규칙
코드는 위에서 아래로 읽혀야 좋다. 이 말은, 추상화 단계가 단계적으로 내려가야 한다는 말이다.
Switch 문
swtich 문을 저차원 클래스에 숨기고 반복하지 않도록 하는 방법이 있다. 다형성을 이용한다.
public abstract class Employee {
public abstract boolean isPayday();
public abstract Money calculatePay();
public abstract void deliverPay(Money pay);
}
public interface EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType;
}
public class EmployeeFactoryImpl implements EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws InvalieEmployeeType {
switch (r.type) {
case COMMISSIONED:
return new CommissionedEmployee(r);
case HOURLY:
return new HourlyEmployee(r);
case SALARIED:
return new SalaryiedEmployee(r);
default:
throw new InvalidEmployeeType(r.type);
}
}
}
서술적인 이름을 사용하기
이름이 길어도 괜찮으니, 서술적인 이름을 고른다. 이름을 붙일 때는 일관성이 있게, 같은 문구, 명사, 동사를 사용하도록 한다.
함수 인수
함수 인수는 무항이면 좋지만 단항, 이항까지는 괜찮다. 다만 삼항부터는 피하도록 한다. 출력 인수는 입력 인수보다 이해하기 어렵다.
단항 형식
인수에 질문을 던지는 경우(isFileExist() 같은 경우), 이벤트 입력의 경우. 이 경우들이 아니라면, 가급적 단항 함수는 피하는 것이 좋다.
StringBuffer transform(StringBuffer in) 이 void transform(StringBuffer out) 보다 좋다.
플래그 인수
플래그 인수는 자제한다. 함수가 한꺼번에 여러가지 처리한다는 것을 알리는 꼴이기 때문이다.
이항 함수, 삼항 함수
함수의 인수에 오해를 사거나 실수를 불러 일으키는 경우(assertEquals(expected, actual)) 과 같은 경우들이 있으므로, 피하도록 한다.
인수 객체
인수가 2, 3개 필요하다면 클래스 변수로 선언해서 넘겨주는 방법도 생각해본다.
동사와 키워드
단항 함수는 함수와 인수가 동사/명사 쌍을 이뤄야한다. write(name) 보다 writeField(name) 이 좋고, assertEquals 보다 assertExpectedEqualsActual(expected, actual) 이 더 좋다.
부수 효과를 일으키지 말 것
하겠다고 선언한 것 외의 일을 하지 않도록 한다. 예를 들어 password 를 체크하는 함수에서 session을 초기화한다던지, 선언된 함수와 다른 일을 하는 것은 좋지 않다.
명령과 조회를 분리하기
함수는 뭔가를 수행하거나 답하거나 둘 중 하나만 수행하도록 한다.
if (attributeExists("username") {
setAttribute("username", "unclebobb");
...
}
오류 코드보다 예외를 사용하기
오류 코드 대신 예외를 사용하면, 오류 처리 코드가 원래 코드에서 분리되는 효과를 가져오므로 가독성을 높일 수 있다.
try/catch 블록은 별도의 함수로 뽑아내는 편이 좋다.
public void delete(Page page) {
try {
deletePageAndAllRef(page);
}
catch (Exception e) {
logError(e);
}
}
private void deletePageAndAllRef(Page page) throws Exception {
deletePage(page);
registry.deleteRef(page.name);
configKeys.deleteKey(page.name.makeKey());
}
반복하지 말기
당연한 말이지만, 반복은 가독성을 악화시킬 뿐 아니라, 실수 및 오류의 확률을 높인다.
구조적 프로그래밍
모든 함수와 함수 내 모든 블록에 입구와 출구는 하나여야 한다. 즉, return 문은 하나여야한다.
break, continue 사용을 해선 안되고, goto는 절대로 안된다.
'[ Review ]' 카테고리의 다른 글
Clean Code - 4장 주석 (3) | 2024.03.14 |
---|