Clean Code

좋은 코드

  • 유지보수성

나쁜 코드

  • 반복적으로 나타나는 중복된 코드가 악취나는 코드

중복 코드

  • 여러 코드에 퍼져있는 반복되는 코드를 별도 모듈로 분리하여 유지보수성을 높이는게 중요

  • 함수로 분리하고 명확한 네이밍을 지어 로직을 이해하기 쉽게 만듦

매직 상수

  • 매직 상수란 특정 값을 하드코딩한 것을 의미

  • 나중가면 이게 무슨 뜻인지 알수가 없게됨

  • 개선 방법

    • 숫자에 의미를 담기

    • 흩뿌려진 상수 모으기

이름 짓기

코드를 읽었을 때 그 이름대로 예측 및 유추하게 된다. 예측한대로 동작하게 만드는게 좋은 이름 짓기 방법이다.

  • 구체적인 이름 짓기

  • 관례를 따르기, 각 언어 생테계에 따라 관례가 존재한다.

  • 정보를 담기

    • 네이밍과 동작이 동일해야 한다.

  • 읽는 사람 입장에서 최대한 뇌빼고 이해할수 있도록 짓는게 중요

  • 컨텍스트 내에서 물흐르듯이 이해할 수 있도록 간단 명료하게 작명해야 한다.

오류 관련

  • null 관련한 문제

  • 자바의 null 문제를 언어 차원에서 방지한 것이 코틀린 언어

흐름 제어

  • ifswitch

  • 중첩을 최소화하기

  • 중첩이 많다는것은 많은 악취를 포함한다.

    • 너무 많은 일을 함

    • 너무 많은 조건을 갖고 있음

    • 너무 많은 상태를 알고 있음

    • 즉, 복잡하다. -> 유지보수하기 어렵다.

사용하지 않는 코드

  • 사용되지 않는 코드는 읽는사람으로써 혼란을 야기시킴

  • 사용되지 않는 코드는 남겨두지 않고 과감하게 제거하는게 필요

함수

  • 재사용 가능한 코드 조각

  • 특정 작업을 수행하는 명령어의 조합

  • 입력을 받아 특정 명령을 수행하거나, 결과를 반환

  • 모듈화, 재사용성, 구조화, 관리

함수 관련 클린코드

작게 만들기

  • 작아야 읽기 쉽고 수정하기 쉽다. 즉, 유지보수하기 쉬운 코드가 된다.

  • 15 line 이하가 작다고 표현됨

함수를 작게 만드는 방법

  • 메서드 추출

  • 메서드를 메서드 객체로 대체

    • 복잡한 메서드를 단순화하고 가독성을 높이기 위해 사용됨

복잡도를 낮추기

  • 함수 안의 분기 개수를 작게 유지

  • if, switch, 삼항연산, try & catch, for, &&, ||

  • 분기점이 많을수록 복잡도가 증가한다.

파라미터 개수를 제한하기

  • 4개 이하

  • 4개를 초과하면 파라미터 객체를 고려

각 함수는 하나의 일만 잘하기 (단일 책임)

  • 하나의 함수 안에서 여러가지 일을 하지 말자.

  • 복잡하고, 테스트가 어렵게됨

Class

단일 책임 원칙 (SRP)

  • 각 클래스는 하나의 책임만 갖음

  • 2개 이상의 역할을 수행하면 복잡성이 높아짐

  • 더 작고, 더 응집된 클래스를 만들려고 노력

의미 있는 클래스 이름 짓기

  • 클래스 이름만 보고 어떤 클래스인지 알 수 있어야 함

  • 명확하고 설명적인 이름

  • 클래스의 목적과 책임이 들어나야 함

캡슐화

  • 접근 제어자 public, private, protected를 사용하여 클래스 멤버의 가시성을 관리

생성자

  • 생성자에 복잡한 논리나 작업을 피한다.

    • 복잡한 로직은 별도 메서드로 추출

  • 생성자는 로직을 넣지 않는 것이 중요

의존성 주입

  • 클래스는 다른 클래스를 사용하여 의존성이 생기게 됨

  • 의존성을 낮추는것이 복잡성을 줄인다.

  • 외부에서 주입해주는 방식으로 사용해야 목 데이터로 갈아끼워 테스트하기도 쉽고 교체 방식으로 클래스의 별도 수정없이 행동을 바꿀수 있게 된다.

인터페이스 활용

  • 유연성이 높아지고, 다형성을 사용하기 쉬워짐

interface Logger {
  void log(String message);
}

class FileLogger implements Logger {
  @Override
  public void log(String message) {
    //
  }
}

상속을 과용하지 않고, 효과적으로 사용

  • 상속 대신 조합(Composition)을 권장

  • 상속을 사용하면 부모 클래스에 모두 접근 가능하기 때문에 캡슐화가 깨진다.

  • 상속은 간단한 곳에서만 사용하도록!

'신'을 만들지 않기

  • 클래스 하나에 모두 작성하지 않고 책임에 맞게 별도 클래스로 분리하는것이 중요

  • 클래스와 관련된 모든 로직을 다 때려박은 클래스를 "God Class" 라 부른다.

관레를 따르기

  • 일관된 코딩 스타일로 작성

하드코딩 피하기

  • 상수나 매직 넘버를 코드에 직접 하드코딩하는 것을 피한다.

  • 명명된 상수나 열거형을 사용

클래스 크기를 작게 유지하기

  • 클래스와 관련 없는 것들을 별도 클래스로 분리

  • 작고 응집도 높은 클래스 만들기

모듈

  • 응집된 코드와 관련 리소스 집합

단일 책임 원칙

  • 하나의 책임을 갖도록 유지

  • 둘 이상의 일을 수행하면 복잡도 증가

모듈의 독립성

  • 하나의 모듈이 다른 모듈의 내부 세부 사항에 의존하지 않도록 한다.

  • 강결합으로 변경이 어려움

모듈의 크기

  • 작게 유지

  • 응집되게 관리

모듈간의 의존성

  • 인터페이스와 추상화 활용

  • 특정 구현부는 인터페이스 안에 숨김

모듈 버전 관리

  • 모듈을 외부에 배포하거나, 공유하는 경우 버전 관리 필요

  • 모듈에 의존하는 프로젝트와 호환성 유지

모듈의 일관성

  • 각 모듈은 일관성을 유지

  • 동작 방식도 유사하도록 설계 및 구현

관심사를 모듈로 분리

  • 각각의 관심사가 다르다면 별도 모듈로 분리

Last updated