본문 바로가기
독서

'클린 코드'를 읽고

by graygreat 2021. 11. 27.
728x90
반응형

읽기 전 클린 코드에 대한 생각

  • 내 코드는 과연 어떤가?
  • 좋은 코드란 무엇인가?
  • 이 책을 보면 좋은 코드를 짤 수 있을까?

지키고 싶은 규칙&개념

1. 함수는 한 가지를 해야 한다

  • 안녕하세요

    • 박준형입니다.
  • 한 가지의 기준은 어디까지일까?

  • 많이 사용하는 if-else문, switch문을 사용할 때, 함수는 한 가지 일을 하지 않는다.

    • SRP 위반
    • OCP 위반
    • enum type 또는 다형성을 사용해 구현 가능

기존 코드

  • 함수가 값을 변환해주는 일뿐만 아니라 어느 타입인지 확인
  • 한 가지 이상의 일

변경된 코드

  • EnumType을 사용하여 메소드가 변환하는 일만 할 수 있도록 변경

2. 서술적인 이름을 사용하라

  • 변수명, 메소드명, 클래스명을 정하는 것에 있어서 많은 고민을 하게 된다.
  • 나름대로 생각하고 정하게 됐는데 이후 이름이 겹치는 상황이 생긴다.

경험

  • Message의 전반적인 비즈니스 로직을 담당하는 MessageService를 먼저 구현
  • 이후 Email, AlimTalk, TextMessage를 추상화하는 추상 클래스를 만들 때, MessageService라는 이름을 사용하고 싶었지만 이미 존재하는 이름
  • 이름을 정할 때, 길어도 되니 조금 더 유의미한 서술적인 이름 사용하기
  • 책에서도 완벽한 가이드를 주진 않음

3. 수직거리

  • 서로 밀접한 개념은 세로로 가까이 둬야 한다.

경험

  • 기존 나의 코드는 접근 지정자별로 위치를 둠

    • 이렇게 하게 되면 소스 파일을 위아래도 뒤지는 상황이 발생
  • 접근 지정자와 상관없이 수직적으로 코드를 작성하면 자연스럽게 코드를 읽을 수 있음

  • 호출되는 함수를 호출하는 함수보다 나중에 배치

4. 구현을 감추려면 추상화가 필요하다

경험 1

  • 처음 EmailService, AlimTalkService, TextMessageService를 구현할 때, 추상화하지 않고 각각 구현한 다음 messageType에 맞게 선택
  • SendingService로 추상화하고 SendingFactory를 사용하여 service를 선택할 수 있도록 구현
  • 추상화 뒤로 자료를 숨기고 messageType에 맞는 함수만 사용할 수 있음

경험 2

  • MessageRepository를 추상화 하여 JpaRepository 인터페이스 사용을 감춤
  • 구현을 감추는 것뿐만 아니라 확장도 쉽게 할 수 있음

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

경험

  • Controller 단에서 발생하는 예외에 대해서는 @RestControllerAdvice를 사용하여 ExceptionHandler를 구현
  • consume한 데이터들은 try-catch를 사용하여 예외 처리
  • logging 기능을 사용하여 catch 블록에서 오류를 기록하도록 함

6. 깨끗한 경계

  • 소프트웨어 설계가 우수하다면 변경하는데 많은 투자와 재작업이 필요하지 않다.
  • 작업을 할 때 구조를 변경하거나 생각이 바뀌어 많은 시간을 투자해야 하는 경우가 많다.
    • 경계를 잘 나누고 설계를 잘해야 이후 투자하는 시간을 줄일 수 있다.

7. TDD

  • 테스트 코드는 실제 코드 못지않게 중요하다.

  • 테스트 코드가 있으면 변경이 두렵지 않다.

  • 테스트 코드가 없다면 모든 변경이 잠정적인 버그다.

  • 현재 기능을 구현하는 것에만 집중해서 테스트 코드를 뒷전으로 미뤄두고 있다.

    • 갚아야 할 부채가 생긴다.
    • 일정에 맞춘 기능 구현을 우선시하다 보니 테스트 코드 작성을 소홀히 하게 된다.
    • 적절히 분배하는 법을 익혀야 할 것 같다.

8. 클래스는 작아야 한다

  • 클래스는 하나의 책임을 가진다.

    • 기준을 정하기가 애매한 것 같다.

경험

  • MessageService라는 클래스에 save, update, cancel 메소드가 정의

    • Message를 관리하는 서비스의 측면으로 보면 하나의 책임
    • 저장, 수정, 취소로 보면 여러 개의 책임
    • 어떻게 클래스를 나눠야 할까?

9. 변경하기 쉬운 클래스

  • 코드에 손대면 위험이 생긴다. 다른 코드를 망가뜨릴 잠정적인 위험이 존재한다.

  • 상세한 구현에 의존하면 안 된다.

  • OCP, DIP를 생각하며 코드를 구현해야 한다.

    • 상세한 구현이 아니라 추상화에 의존해라.

10. 창발적 설계로 깔끔한 코드를 구현하자

  • 켄트 백이 제시한 단순한 설계 규칙 네 가지

    • 모든 테스트를 실행한다.
    • 중복을 없앤다.
    • 프로그래머 의도를 표현한다.
    • 클래스와 메소드 수를 최소로 줄인다.

경험

  • 모든 테스트를 실행한다.

    • 테스트 코드를 지속적으로 만들지 못하고 있지만, 이것은 잘못된 습관이다.
    • 미루지 말자.
  • 중복을 없앤다.

    • 당장 코드를 이쁘게 작성하는 것이 어렵다면 그냥 무식하게 작성한다.
    • 그 후 중복되는 코드가 있으면 메소드를 추출한다.
  • 프로그래머 의도를 표현한다.

    • 좋은 이름을 선택한다.
  • 클래스와 메소드 수를 최소화한다.

    • 너무 줄이려고 하면 득보다 실이 많아진다.
    • 책에서는 이 규칙은 가능한 줄이라고 제안한다.

결론

  • 내 코드에 대해 되돌아볼 수 있는 시간이 되었다.
  • 리팩토링을 꾸준히 해야 좋은 코드를 만들 수 있을 것 같다.
  • 연차가 쌓여도 다시 꺼내 읽어봐야 할 책인 것 같다.

경험을 대신할 단순한 개발 기법이 있을까? 당연히 없다.

반응형

댓글