Skip to content

3장 함수

김윤수 edited this page Jul 24, 2022 · 1 revision

작게 만들어라

  • 함수를 만드는 첫 번째 규칙은 **‘작게!’**다.
  • 두 번째 규칙은 **‘더 작게!’**다.
  • 조건문에 들어가는 블록은 한 줄이어야한다.

한 가지만 해라

  • 함수는 한 가지를 해야한다. 그 한 가지를 잘 해야한다. 그 한 가지만을 해야한다
  • 저장된 함수 이름 아래에서 추상화 수준이 하나인 단계만 수행해야한다
  • 의미있는 다른 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하고 있는 것이다.

함수 하나 당 추상화 수준은 하나로

  • 추상화 수준을 섞으면 표현이 근본 개념인지 세부사항인지 구분하기 어렵다.

내려가기 규칙

  • 위에서 아래로 이야기처럼 읽혀야 좋다
  • 함수 추상화 수준이 한 번에 한 단계씩 낮아진다.

Switch문

  • 장황한 switch문의 반복은 추상 팩토리 & 다형성 객체 생성 코드로 개선할 수 있다.
  • 왜 쓰면 안될까?
    1. 함수가 길다
    2. 한 가지 작업만을 하지 않는다
    3. Single Responsibility Principle(SRP)을 위반한다.
    4. Open Closed Principle(OCP)를 위반한다.

[객체지향 SOLID 원칙](https://www.notion.so/SOLID-3bc31e8045844ed3bebcb4c47007c083)

서술적인 이름을 사용하라

  • 함수가 작고 단순해야하고, 하는 일을 이름에 잘 표현해야한다.

함수 인수

  • 이상적인 개수는 0개, 다음은 1개, 2개이다.
    • why? : 인수는 개념을 이해하기 어렵게 하고 테스트 케이스를 작성하기 복잡해지기때문
  • 인수를 줄이는 방법
    • 인수를 현재 클래스 static 변수로 만든다.
    • 별도 클래스를 작성, 인수를 생성자로 받아 그 클래스를 static 변수로 만들고, 그 클래스 내에서 메소드를 구현
    • 인수 클래스에 메소드를 추가하고 기존 클래스에서 객체, 메소드형태로 호출한다
    • 인수가 2~3개 이상 필요하다면, 인수를 독자적인 클래스 변수로 선언한다.
  • 단항 함수가 적절한 경우
    • 인수에 질문을 던지는 경우
    • 인수에 뭔가 변환해 결과로 반환하는 경우
    • 입력인수로 시스템 상태를 바꾸는 경우(이벤트 메소드)
  • 이항 함수가 적절한 경우
    • 인수 2개가 한 값을 표현하고, 자연적인 순서가 있는 경우
  • 삼항 함수가 적절한 경우
    • 부동 소수점 비교
  • 플래그 인수 금지(boolean 인수는 피하기)
    • 플래그값에 따라 별도의 함수를 작성하기
  • 가변 인수(인수의 갯수가 변화함)
    • ex) String.format(”%s worked %.2f hours”, name, hours);
  • 동사와 키워드
    • 단항 함수는 함수와 인수가 동사/명사 쌍을 이뤄야한다
      • ex) write(name)
    • 함수 이름에 인수에 대한 키워드를 추가하라.
      • ex) write(name) → writeField(name)
      • ex) assertEquals() → assertExpertedEqualsActual(expected, actual)

부수효과를 일으키지마라

  • 예상치 못한 부수 효과는 시간적인 결합, 순서 종속성을 초래하게된다.
  • 함수는 한 가지 기능만을 하도록 작성한다.

명령과 조회를 분리하라

  • 함수는 뭔가 수행하거나, 뭔가에 답하거나 둘 중 하나만 해야한다.
  • 나쁜 예
if( set("username", "myname"))
...
  • 좋은 예
if(attributeExists("username"){
	setAttribute("username", "myname");
}

오류 코드보다 예외를 사용하라

  • 오류코드를 반환하는 방식은 여러 단계로 중첩되는 코드를 야기한다
  • 오류 코드를 반환하는 방식은 오류코드를 곧바로 처리해야한다는 문제를 발생
  • 오류 코드를 정의하는 의존성 magnet은 재컴파일, 재배치를 요구하므로 번거로워진다
  • Try/Catch 블록
    • try/catch 블록은 별도 함수로 뽑아내고, try 문에서 실제 ‘작업'메소드를 호출한다.
    • 실제 작업을 하는 코드에서는 throws expection 하여 모든 예외 처리를 한 곳에서 처리한다.
  • 반복하지마라
    • 코드 길이가 증가하고, 알고리즘이 변하면 중복된 코드 모두 수정해야하며 오류발생확률도 올라간다

구조적 프로그래밍

  • 모든 함수와 함수 내 모든 블록에 입구와 출구가 하나만 존재해야함.
  • 함수가 아주 클때, 구조적 프로그래밍의 목표와 규율이 효과적이다.