로버트 C. 마틴의 Clean Code 라는 책을 읽고, 학습하고 정리하는 글 입니다.


Clean Code 클린 코드 애자일 소프트웨어 장인 정신

  • 읽은 날짜 : 23.07.16 ~ 23.07.26
  • 읽은 범위 : 3장 함수
  • 주요 키워드 :
    함수 짧게 함수명

✅ 3장 함수

  • 어떤 프로그램이든 가장 기본적인 단위가 함수다.

✍ 함수를 잘 만드는 법

- 작게 만들어라

  • 함수는 100줄을 넘어서는 안 된다. 아니 20줄도 길다.
  • 블록과 들여쓰기
    • if문/else문/ while문 등에 들어가는 블록은 한 줄이어야 한다.
      why? 대게 거기서 함수를 호출하기 때문에 함수 이름을 적절히 짓는다면 함수가 작아질 뿐만 아니라 코드를 이해하기도 쉬워진다.
    • 함수에서 들여쓰기는 2단을 넘어서면 안된다. 그래야 읽고 이해하기 쉬워진다.

- 한 가지만 해라

함수는 한 가지를 해야 한다. 그 한 가지를 잘해야 한다. 그 한 가지만을 해야 한다.

  • 지정된 함수 이름 아래에서 추상화 수준이 하나인 단계만 수행한다면
    그 함수는 한 가지 작업만 한다.
  • 우리가 함수를 만드는 이유는 큰 개념(함수 이름)을 다음 추상화 수준에서 여러 단계로 나눠 수행하기 위해서가 아니던가.

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

  • 함수가 확실히 한 가지 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 한다.
  • 위에서 아래로 코드 읽기 : 내려가기 규칙
    • 한 함수 다음에는 추상화 수준이 한 단계 낮은 함수가 온다.
    • 위에서 아래로 프로그램을 읽으면 함수 추상화 수준이 한 번에 한 단계씩 낮아진다. → 내려가기 규칙
    • 위에서 아래로 코드를 구현하면 추상화 수준을 일관되게 유지하기가 쉬워진다.

- Switch문

  • switch문을 작게 만들고 한 가지 작업만 하게 만들기는 어렵다.
    (본질적으로 switch문은 n가지 일을 처리한다.)
  • 각 switch문을 저차원 클래스에 숨기고 절대로 반복하지 않는 방법은 있다.
    • 다형성(polymorphism)을 이용한다.
    • switch문을 추상 팩토리에 숨기고 적절한 파생 클래스의 인스턴스를 생성한다. 함수들은 인터페이스를 거쳐 호출되고, 그러면 다형성으로 인해 실제 파생 클래스의 함수가 실행된다.

- 서술적인 이름을 사용하라

  • 길고 서술적인 이름이 짧고 어려운 이름보다 좋고, 길고 서술적인 이름이 길고 서술적인 주석보다 좋다.
  • 함수 이름을 정할 때는 여러 단어가 쉽게 읽히는 명명법을 사용하고, 여러 단어를 사용해 함수 기능을 잘 표현하는 이름을 선택한다.
  • 서술적인 이름을 사용하면 개발자 머릿속에서도 설계가 뚜렷해지므로 코드를 개선하기 쉬워진다.
  • 이름을 붙일 때는 일관성이 있어야 한다.

- 함수 인수

  • 함수에서 이상적인 인수 개수는 0개, 다음은 1개, 다음은 2개다. 3개는 피하는 것이 좋다.
  • 흔히 우리는 함수에다 인수로 입력을 넘기고 반환값으로 출력을 받는다는 개념에 익숙하다.
    → 코드를 읽는 사람은 코드를 재차 확인하게 된다.
  • 많이 쓰는 단항 형식
    • 인수에 질문을 던지는 경우
      ex) boolean fileExists("MyFile")
    • 인수를 뭔가로 변환해 결과를 반환하는 경우,
      ex) inputStream fileOpen("MyFile")
    • 이벤트 함수
      • 입력 인수만 있고 출력 인수는 없다.
      • 이벤트라는 사실이 코드에 명확하게 나타나야 한다.
      • 이름과 문맥을 주의해서 선택한다.
    • 위의 세가지 경우가 아니면 단항 함수는 가급적이면 피하는게 좋다.
  • 이항 함수
    • 프로그램을 짜다보면 불가피하게 이항 함수를 사용해야 하는 경우도 생기는데, 그만큼 위험이 따른다는 사실을 이해하고 가능하면 단항 함수로 바꾸도록 애써야 한다.
  • 함수에 인수 이름을 넣어 인수 순서를 기억할 필요없게 만들 수 있다.

- 부수 효과를 일으키지 마라

  • 부수 효과가 숨겨진 경우에는 혼란이 커질 수 있다.
  • 일반적으로 출력 인수는 피해야 하고, 함수에서 상태를 변경해야 한다면 함수가 속한 객체 상태를 변경하는 방식을 택한다.

- 명령과 조회를 분리하라

  • 함수는 뭔가를 수행하거나 뭔가에 답하거나 둘 중 하나만 해야 한다.
    (객체 상태를 변경하거나 객체 저보를 반환하거나 둘 중 하나)
  • 명령과 조회를 분리하면 혼란을 피할 수 있다.

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

  • 오류 코드 대신 예외를 사용하면 오류 처리 코드가 원래 코드에서 분리되므로 코드가 깔끔해진다.
  • 정상 동작과 오류 처리 동작을 분리하면 코드를 이해하고 수정하기 쉬워진다.

- 반복하지 마라

  • 중복은 코드가 길어질 뿐 아니라 알고리즘이 변하면 손봐야 한다. 그리고 오류 발생할 확률도 높다.
  • 자료에서 중복을 제거할 목적으로 관계형 데이터베이스에 졍규 형식을 만들었다.
  • 객체 지향 프로그래밍은 코드를 부모 클래스로 몰아 중복을 없앤다.

- 구조적 프로그래밍

  • 모든 함수와 함수 내 모든 블록에 입구와 출구가 하나만 존재해야 한다. - 데이크스트
  • 즉, 함수는 return문이 하나여야 한다.

- 함수를 어떻게 짜죠?

  • 논문이나 기사를 작성할 때 먼저 생각을 기록한 후 읽기 좋게 다듬는 것처럼, 함수를 짤 때에도 처음에는 길고 복잡하고 중복이 있지만 코드를 계속 다듬고, 이름을 바꾸고, 중복을 제거한다. 때로는 전체 클래스를 쪼개기도 한다.

- 결론

  • 함수는 그 언어에서 동사며, 클래스는 명사다.
  • 이 장에서 설명한 규칙을 따른다면 길이가 짧고, 이름이 좋고, 체계가 잡힌 함수가 나오겠지만, 진짜 목표는 시스템이라는 이야기를 풀어나가는 데 있다.
    → 작성하는 함수가 분명하고 정확한 언어로 깔끔하게 맞아떨어져야 이야기를 풀어나가기가 쉬워진다.


💬 느낀점은..

이 장을 읽고 한 번에 내가 함수를 짧고 분명하고 깔끔하게 작성할 수는 없겠지만, 함수를 짤 때마다 한 번씩 생각하면서 조금씩 나아질 수 있도록 열심히 연습해야겠다...!

profile
안녕하세요, 웹 개발자 이하영입니다!

0개의 댓글

Powered by GraphCDN, the GraphQL CDN