노션에서 정리한 내용을 벨로그로 옮겼기 때문에 노션으로 보면 조금 더 보기 더 편합니다🤗
이동하기 → junnkk's Notion
함수를 읽기 쉽고 이해하기 쉽게 하는 방법. 의도를 분명히 표현하는 함수를 구현하는 방법. 처음 읽는 사람이 프로그램 내부를 직관적으로 파악할 수 있도록 하는 속성의 종류.
함수는 작을수록 좋다.
블록과 들여쓰기
if문 / else문 / while문 등에 들어가는 블록은 한 줄이어야 한다.
→ 바깥을 감싸는 함수(enclosing function)이 작아지고 블록 안에서 호출하는 함수 이름을 적절히 짓는 다면 코드를 이해하기 쉬워짐.
함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 하야 한다.
지정된 함수 이름 아래에서 추상화 수준이 하나인 단계만 수행한다면 그 함수는 한 가지 작업만 한다.
단순히 다른 표현이 아니라 의미 있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 한다.
함수 내 섹션
한 가지 작업만 하는 함수는 자연스럽게 섹션으로 나누기 어렵다
함수가 확실히 한 가지 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 한다.
한 함수 내에 추상화 수준을 섞으면 코드를 읽는 사람이 헷갈린다.
∵ 특정 표현이 근본 개념인지 아니면 세부 사항인지 구분하기 힘들기 때문
위에서 아래로 코드 읽기: 내려가기 규칙
코드는 위에서 아래로 이야기처럼 읽혀야 한다.
→ 내려가기 규칙 : 위에서 아래로 프로그램을 읽으면 함수 추상화 수준이 한 번에 한 단계씩 낮아진다.
but 다형성을 이용하여 각 switch 문을 저차원 클래스에 숨기고 반복하지 않는 방법 사용하라
→ switch문을 추상 팩토리에 숨긴다.
예시) Employee and Factory (p48~49)
팩토리는 switc문을 사용해 적절한 employee 파생 클래스의 인스턴스 생성.
calculatePay, isPayday, deliverPay 등의 함수는 Employee 인터페이스를 커쳐 호출
⇒ 다형성으로 인해 실제 파생 클래스의 함수 실행
길고 서술적인 이름이 짧고 어려운 이름보다 좋다 .
함수 이름을 정할 때는 여러 단어가 쉽게 읽히는 명명법 사용 후, 여러 단어를 사용해 기능 잘 표현하는 이름 선택
일관성이 있어야 한다.
→모듈 내에서 함수 이름은 같은 문구, 명사, 동사 사용
함수에서 이상적인 인수 개수 = 0개(무항) (1개(단항) → 2개(이항) → 3개(삼항) → 4개 이상(다항) 순)
⇒ 최선은 인수가 없는 경우. 차선은 입력 인수가 1개인 경우.
많이 쓰는 단항 형식
함수에 인수 1개를 넘기는 이유
이벤트 (드물지만 유용한 단항 함수 형식)
→ 입력인수만 있음
⇒ 이외의 경우에는 단한 함수 피하라.
플래그 인수
플래그 인수 사용 X
이항 함수
Point p = new Point(0,0) 등을 제외하면 되도록 피하라.
삼항 함수
웬만하면 사용 X → 인수의 순서를 인위적으로 기억해야 하므로
인수 객체
객체를 생성해 인수를 줄인다.
인수 목록
인수 개수가 가변적인 함수 필요
ex) String.Fomat
⇒ 사실은 이항 함수이다! public String format(String format, Object... args)
동사와 키워드
함수의 의도나 인수의 순서와 의도를 제대로 표현하려면 좋은 함수 이름 필요
단항 함수 - 함수와 인수가 동사/명사 쌍 ex) writeField(name)
함수 이름에 키워드 추가. 즉, 함수이름에 인수 이름 넣기
ex) assertExpectedEqualsActual(expected, actual)
부수 효과 → 시간적 결함, 순서 종속성 초래
출력 인수
우리는 일반적으로 인수를 함수 입력으로 해석
∴ 일반적으로 출력 인수는 피해야 함. 함수에서 상태를 변경하야 한다면 함수가 속한 객체 상태를 변경하는 방식을 택해야함.
함수는 뭔가를 수행(= 객체 상태 변경) or 뭔가에 답(= 객체 정보 반환)을 해야 함. → 둘 중 하나만!
명령 함수에서 오류 코드를 반환하는 방식은 명령/조회 분리 규칙 위반
⇒ 오류 코드 대신 예외를 사용하면 오류 처리 코드가 원래 코드에서 분리되므로 코드가 깔끔해짐.
Try/Catch 블록 뽑아내기
try/catch 블록은 코드 구조에 혼란을 일으키므로 별도 함수로 뽑아내야 한다.
→ 정상 동작과 오류 처리 동작을 분리하면 코드를 이해하고 수정하기 쉬워진다.
오류 처리도 한 가지 작업이다
오류를 처리하는 함수는 오류만 처리
Error.java 의존성 자석
오류 코드를 반환한다 = 어디선가 오류 코드를 정의한다
public enum Error {
OK,
INVAILD,
NO_SUCH,
LOCKED,
OUT_OF_RESOURCES,
WAITING_FOR_EVENT;
}
오류 코드 대신 예외 사용 → 재컴파일/재배치 없이도 새 예외 클래스 추가 가능
반복을 제거하려는 노력
ex) 자료에서 중복을 제거하기 위해 관계형 데이터베이스에 정규형 생성
ex) 객체 지향 프로그래밍은 코드를 부모 클래스로 몰아 중복 없앰.
ex) 구조적 프로그래밍, AOP, COP 등