Skip to content

Session2 DAY 3

Kimgeunwook edited this page Oct 5, 2021 · 5 revisions

Session2 DAY 3

모임날짜: 2020-12-12(토)
참여자: 강인한, 김근욱, 최승연, 한승엽
주제: 함수 (클린 코드 3장) / API 명세서 작성

Contents

1. 함수

1.1 함수
1.2 규칙


1. 함수 (클린 코드 3장)

목표: 함수를 잘 만드는 방법을 이해하기

1.1 함수

프로그램의 가장 기본적인 단위

  • 함수는 의도를 분명히 표현해야 함 → 어떤 속성을 부여해야 처음 보는 사람도 내부를 직관적으로 파악할 수 있을까?
  • 큰 개념(함수 이름)을 다음 추상화 수준에서 여러 단계로 나누어 수행하기 위해서
1.2 규칙
  1. 작게 만들기 : 함수는 하나의 이야기만 표현한다
  • 중첩구조가 생길만큼 함수는 커져선 안 됨.
  • 블록안에는 1줄이 적당 → 안에서 함수 호출함(호출되는 함수 이름을 잘 지으면 직관적으로 내용파악 가능)
  • 들여쓰기는 최대 2단
  1. 한 가지 일만 하기
  • 판단 방법: 의미 있는 이름으로 달느 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈 p.45 참고
  1. 함수 당 추상화 수준은 하나로!
  • 함수가 확실히 한 가지 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 함
  1. 내려가기 규칙
  • 코드가 위에서 아래로 이야기처럼 읽혀야 좋음 → depth가 깊어질 수록 추상화 수준이 한 단계씩 낮아진다 ex) getHTML(): 추상화 수준 높음 .append("\n") ; 추상화 수준 낮음
  1. Switch문은 숨겨서
    • 본질적으로 N가지 처리 but, 피할 방법은 없음
      • 만약 같은 객체를 가지고 다른 함수가 추가될 경우 또 N번의 분기를 가진 함수가 생겨나는 것임 ex. calaulatePay() 말고 isPaday() 함수가 추가될 때 switch-case 문이 또 생김
    • 숨기는 방법: 다형성을 이용하여 저차원 클래스에 숨김
      • abstract class, interface 를 이용해 다형성 객체 생성
  2. 서술적인 이름 사용하기
    • 코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행하면 ⇒ 클린코드(by 워드)
    • 한 가지만 하는 작은 함수는 이름붙이기가 수월함. 길어도 괜찮음
  3. 함수 인수
    • 최대 2개까지로 제한하기 → 인수는 개념을 이해하기 어렵게 만듦 ⇒ 코드를 읽는 시점에서 중요하지 않는 세부적인 사항까지 알아야 하니까
    • 인수가 많으면 테스트도 어려워짐 → n개의 조합을 모두 test해봐야 하니까 [예시]
    • 단항 함수
      1. 인수에 질문을 던지는 경우 ex. boolean fileExists("MyFile")
      2. 인수를 뭔가로 변환해 결과를 반환하는 경우 ex. InputStream은 인자로 들어온 file을 InputStream으로 변환함
      3. 이벤트 처리 ex. 입력 인수를 해석해 시스템 상태를 바꿈
    • 플래그 인수
      1. 추 하 다 → 함수가 여러 가지를 처리한다고 공표하는 격임
    • 이항 함수
      • 자연적인 순서에 의해 2개인건 ㄱㅊ ex. Point클래스(좌표는 점 2개니까)
      • assertEquals(expected, actual)은 자연적인 순서가 아니므로 순서를 기억해야한다는 단점이 있음
    • 인수 객체
    • 동사와 키워드
      • 단항 함수: 함수와 인수가 동사/명사 쌍을 이뤄야 함 ex. write(name)은 '이름을 쓴다'라는 뜻 → writeField(name)은 '이름'이란 '필드'를 '쓴다'라는 뜻 //더 명확하고 좋음
      • 함수 이름에 키워드(인수 이름)추가 → 인수 순서를 기억할 필요 없음 ⇒ assertEquals → assertExpectedEqualsActual
  4. 부수 효과를 일으키지 마라
    • 함수에서 약속한 기능말고 다른 일을 하지 말 것 ex. 인수나 시스템 전역 변수를 수정함
    • 의도하지 않은 채로 시간적 결합은 혼란을 일으킬 수 있음 ex. 비밀번호만 체크하겠다고 해놓고, 세션까지 초기화 해버리는 함수는 잘 못 호출했을 때 문제 생길 수 있음
      → 인수의 값이 함수에서 바껴서 호출한 곳에서 쓰는 경우?!? ⇒ 개별로임
  5. 명령과 조회를 분리하기
    • 함수는 뭔가를 수행하거나 뭔가에 답하거나 둘 중 하나만 해야 함 ex. if(set("username", "ddeung")) //1번: username이 ddeung이라면 //2번: username을 ddeung으로 바꾸는데 성공한다면 혼란을 야기할 수 있음 ⇒ if(attributeExists("username")){ setAttribute("username", "ddeung"))} 이 더 좋은 구조
  6. 오류코드보다 예외 사용하기
    • if문에 명령문이 들어가서 오류코드를 반환할 경우 → 호출한 함수에서 오류 코드에 따른 핸들링을 해야함 ⇒ 함수의 depth가 자연적으로 깊어질 수 밖에 없음 ⇒ 오류코드 반환 부분을 try-catch로 뽑기 // catch 에서 exception으로 처리함 ⇒ try-catch도 사실 추한 구조임 ⇒ 에러 발생 가능성있는 부분을 따로 함수로 만들고, 메인 로직을 처리하는 함수에선 예외 처리 안하도록 만들기
    • 즉, 정상 동작과 오류 처리 동작을 분리하여 만들자
    • 오류 처리도 한 가지 작업임 → 함수로 따로 빼내서 처리하기(오류만 처리시킴)
    • 저자는 오류코드 방식보다 예외처리 방식 추천 → 오류코드는 새로운 코드 추가가 번거로움
  7. 반복하지 마라
    • 한 함수 내에 중복되는 것이 있다면, 하나 고칠경우 수작업으로 다 고쳐야함
    • 소프트웨어는 중복을 제거하는 쪽으로 발전해옴 ex. RDB의 정규화, AOP 등등

Clone this wiki locally