MATT's

클린 코드(Clean Code) 란? 본문

개발etc

클린 코드(Clean Code) 란?

matt5659 2022. 10. 3. 20:07
읽기 쉬운 코드가 클린 코드(Clean Code)이다.

 

클린 코드를 한 마디로 정의하라고 하면, 위와 같이 정의할 수 있을 것 같다.
그만큼 클린 코드의 가장 중요한 요소 중 하나는 가독성이라고 할 수 있다.
즉, 모든 사람이 이해하기 쉽도록 작성된 코드를 말한다.

가독성이 왜 중요할까?

일반적으로 기존 코드를 변경하고자 할 때, 해석하는 시간과 수정하는 시간의 비율은 10:1 정도라고 한다.
즉, 코드를 변경하기 위해 걸리는 총 시간이 11시간이라고 한다면, 그 중 코드를 분석하는데 소요되는 시간이 10시간 정도라는 뜻이다.
해석이 어려운 코드를 수정하는데는 그만큼 분석에 소요되는 시간이 더 오래 걸리기 때문에 가독성이 중요한 것이다.
또한 대부분의 결함은 기존 코드를 수정하는 동안 발생된다고 하니 오류의 위험성을 최소화 시키기 위해서라도 가독성이 뛰어난 코드를 작성하는 것이 중요하다.

어떻게 클린한 코드를 작성할 수 있을까?

1) 의미 있는 이름

대부분의 개발자 들이 가장 어려워하는 일 중 하나가 '변수 명 정하기'인데, 아래와 같은 원칙을 지키면 보다 쉽게 의미있는 이름을 지을 수 있다고 한다.

  • 의도를 분명히 밝히기
    • 이름이 존재 이유, 수행 기능, 사용 방법을 대변 해야한다.
    • 이름을 설명하는 주석이 필요하지 않아야 한다.
  • 그릇된 정보 피하기
    • 널리 쓰이는 의미가 있는 단어를 다른 이유로 사용하면 안된다.
    • 유사한 이름을 사용하면 안된다.
  • 의미 있게 구분하기
    • 이름이 다르면 의도도 달라야 한다.
    • info, data와 같이 애매한 의미의 단어는 피하는게 좋다.
  • 검색하기 쉬운 단어를 사용하기
    • 짧은 단어보다 긴 단어를 사용한다.
  • 클래스 이름은 명사를 사용한다.
  • 메소드(함수) 이름은 동사를 사용한다.
    • 표준에 따라 get, set, is를 사용한다.
    • 생성자를 중복 정의할 때는 정적 팩토리 메소드를 사용하는 것이 좋다.

2) 함수 (메소드)

개인적으로 클린 코드를 작성하는 방법 중 가장 쉽고 가장 효과적인 방법은 '한 개의 함수는 하나의 일만 하도록 작성한다.' 라고 생각한다.
긴 함수를 여러 함수로 쪼개어 분리하기만 해도 가독성이 훨씬 올라가게 되고, 그만큼 유지보수 성이 올라가기 때문이다.
그 외에도 함수(메소드) 작성 시에 지켜야할 원칙은 아래와 같다.

  • 작게 만들기
    • 함수 안의 줄 수는 적을수록 좋다.
  • 한 가지 역할만 하기
    • 앞서 말한 것처럼 함수는 한가지 일을 하는 함수 들과 그 함수 들을 호출하는 함수로 이루어져야 한다.
    • 의미 있는 이름으로 함수를 추출할 수 있다면, 그 함수는 한가지의 역할 만을 한다고 할 수 있다.
  • 함수 인수(argument)를 최대한 적게 사용하기
    • 함수에 인수는 적을수록 좋다.
    • 입력 값이 있는 변환 함수는 반환 값이 있도록 작성하는 것이 좋다.
    • 플래그 인수 (ex. isTrue)는 사용하지 않는 것이 좋다.
    • 인수가 많이 필요하다면 클래스를 추가로 생성하여 사용하는 방안을 고려해보는 것도 좋다.
  • 명령과 조회를 분리하기
    • 함수는 무언가를 수행하거나 답하거나 둘 중 하나만 해야한다.

3) 주석

'주석은 가능한 적은 것이 좋다.'

이 말은 사실 '주석은 필요없으니 안쓰는게 좋다.' 라는 의미가 아니라 '주석이 필요 없을 만큼 표현이 깔끔한 코드를 작성하는 것이 좋다.' 라는 의미로 받아들이는게 더 맞을 것 같다.
주석이 어수선하게 많이 달려있다는 것은 설명이 많이 필요하다는 것이고 그만큼 코드가 깔끔하지 못하다는 것을 반증하기 때문이다.
(* 친구 들과 '설명이 필요한 드립(개그)은 실패한 드립(개그)이다.' 라는 말을 자주하는데, 그것과 비슷한 맥락인 것 같다.)
위에서 말한 것처럼 주석이 필요 없다는 것은 아니다.
나쁜 주석은 사용하지 않고, 좋은 주석만 사용하여 조금 더 깔끔하게 보일 수 있도록 하는 것이 중요하다.

  • 좋은 주석
    • 코드로 표현하지 못하는 정보를 제공하는 주석
    • 의도를 설명하는 주석
    • 결과를 경고하는 주석
    • 중요성을 강조하는 주석
  • 나쁜 주석
    • 코드로 설명이 가능한데, 코드를 설명하는 주석
    • 주석으로 처리한 코드
    • 이력을 기록하는 주석

4) 객체

  • SRP(Single Responsibility Principle, 단일 책임 원칙)을 지켜야 한다.
    • SRP는 '클래스는 단 한 개의 책임을 가져야 한다.'라는 의미를 뜻한다.
    • 객체 역시 함수와 마찬가지로 간결하게 작성하는 것이 중요하며, 단일 책임 원칙에 따라 한 가지의 책임 만을 가져야 한다.
  • 디미터 법칙을 지켜야 한다.
    • 디미터 법칙은 '모듈이 호출하는 객체의 속사정을 몰라야 한다.'는 것이다.
    • 객체는 자료를 그대로 노출하면 내부 구조가 드러나게 되고, 결합도가 높아지게 되기 때문에,
      자료를 숨기고 함수를 공개해야 한다.

5) 오류 처리

  • 오류 코드보다 예외를 사용하는 것이 좋다.
  • 미확인 예외를 사용해야 한다.
    • 확인된 예외는 상위 선언부에서 모두 선언해주어야 하기 때문
  • 예외에 의미를 제공해야 한다.
  • 호출자를 고려하여 예외 클래스를 정의해야 한다.
    • 외부 라이브러리를 사용할 때, 외부 라이브러리용 예외 클래스를 사용하는 것도 좋은 방법이다.
  • 예외 상황에 null을 반환하여 판단하지 않아야 한다.

6) 단위 테스트

  • TDD(Test Driven Development)로 개발해야 한다.
    • 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.
    • 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.
    • 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.
  • 테스트는 유연성, 유지 보수성, 재사용성을 제공한다.
  • 테스트는 실제 코드보다도 더 가독성이 중요하다.
  • 테스트 당 개념 하나 만을 테스트한다.
    • 테스트의 assert를 최소로 하는 것이 좋다.
    • 테스트 함수 하나는 개념 하나 만을 테스트하는 것이 좋다.
  • F.I.R.S.T 원칙을 지켜야 한다.
    • Fast : 테스트는 빠르게 동작해야 한다.
    • Independent : 테스트는 서로 의존하지 않고, 독립적으로 동작해야 한다.
    • Repeatable : 테스트는 어떤 환경에서도 반복이 가능해야 한다.
    • Self-Validating : 결과값은 boolean이여야 한다. (성공 / 실패)
    • Timely : 실제 코드 구현 전에 작성해야 한다.

'개발etc' 카테고리의 다른 글

파일 동기화 - rsync  (0) 2021.10.04
파일 동기화 - lsyncd  (0) 2021.10.04
MVC, MVVM 패턴  (0) 2020.05.30
[VSCode] 유용한 플러그인 설치 및 설정  (0) 2020.05.30
프로그래밍 명명 규칙 (Naming Rule)  (0) 2020.05.17