Clean Code 2장

2장 의미 있는 이름

의도를 분명히 밝혀라

  1. 존재 이유
  2. 수행 기능
  3. 사용 방법

위와 같은 목적을 다 나타낼 수 있어야한다.
만약, 주석이 필요하다면, 의도를 분명히 드러내지 못한 것이다.

코드가 간단해도 하는 일을 짐작하기 어렵다면?

for (int[] x: theList) {
    if (x[0] == 4) {
        list.add(x);
    }
}
return list;

위 코드는 코드 자체에 명시적으로 맥락이 들어나지 않는다. 해당 함수에서 theList, 0번째 값, 4, list가 의미하는 것을 알 수 없다.
여기서 중요한 것은 함축성이다.
지뢰찾기 게임을 만든다고 생각하자.
theList: 게임판 => gameBoard
0번째 값: 칸의 상태 => STATUS_VALUE = 0
4: 깃발이 꽃힌 상태 => FLAGGED = 4
list: 깃발이 꽃힌 칸들의 집합 => flaggedCells

List<int[]> flaggedCells = new ArrayList<int[]>();
for (int [] cell : gameBoard) {
    if (cell[STATUS_VALUE] == FLAGGED) {
        flaggedCells.add(cell);
    }
}
return flaggedCells;

이와 같이 코드를 명확하게 작성할 수 있다.
더 나아가 isFlagged라는 함수를 통해 FLAGGED 상수를 감춰도 좋다.

그릇된 정보를 피하라

  • 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용하면 안된다.
    • ex) 프로그래머에게 List는 특수한 의미
  • 서로 흡사한 이름을 사용하지 않도록 주의한다.
  • 유사한 개념은 유사한 표기법을 사용한다.(일관성)

의미 있게 구분하라

  • 이름이 달라야 한다면, 의미도 달라져야한다.
  • 연속된 숫자를 덧붙이거나 불용어를 추가하는 방식은 적절하지 못하다.
    • 아무런 정보를 제공하지 못한다.
    • 불용어는 중복이다.
    • Info, Data는 a, an, the와 같이 의미가 불분명하다.

발음하기 쉬운 이름을 사용하라

  • 발음하기 어려운 이름은 토론하기도 어렵다.
  • 발음하기 쉬운 이름은 지적인 대화가 가능해진다.

검색하기 쉬운 이름을 사용하라

  • 문자 하나를 사용하는 이름, 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다.
  • 간단한 메서드에서 로컬 변수만 한 문자를 사용한다.
    • 이름 길이는 범위 크기에 비례해야 한다.
  • 이름을 의미있게 지으면 함수가 길어지지만, 검색하기 쉽다.

인코딩을 피하라

멤버 변수 접두어

  • 멤버 변수를 다른 색상으로 표시하거나 눈에 띄게 보여주는 IDE를 사용해라
  • 코드를 읽을수록 접두어는 관심 밖으로 밀려난다.

인터페이스 클래스와 구현 클래스

  • 인터페이스 이름은 접두어를 붙이지 않는 편이 좋다.

자신의 기억력을 자랑하지 마라

  • 코드를 읽으면서 변수 이름을 자신이 아는 이름으로 변환해야 한다면, 해당 변수명은 바람직하지 못하다.
  • 루프에서 반복 횟수 변수는 i, j, k를 사용해도 좋다. 하지만, 그 외에는 부적절하다.
  • 명료함이 최고다.
  • 남들이 이해하는 코드를 짜야한다.

클래스 이름

  • 명사나 명사구가 적합하다
  • Manager, Processor, Data, Info 등과 같은 단어는 피한다.

메서드 이름

  • 동사나 동사구가 적합하다.
  • 생성자를 중복정의할 때는 정적 팩토리 메서드를 사용한다.
    • 이때, 메서드는 인수를 설명하는 이름을 사용한다.
    • 생성자 사용을 제한하기 위해서는 생성자를 private로 선언한다.

기발한 이름은 피하라

  • 재미난 이름보다 명료한 이름을 선택하라
  • 특정 문화에서만 사용하는 농담은 피하는 편이 좋다.

한 개념에 한 단어를 사용하라

  • 똑같은 메서드를 클래스마다 제각각으로 부르면 혼란스럽다.
    • ex) 어떤 데이터를 가져올 때, fetch, retrieve, get를 섞어 쓰지 말자
  • 메서드 이름은 독자적이고 일관적이어야 한다.
    • 주석을 뒤져보지 않고도 올바른 메서드를 선택하는데 도움이 된다.

말장난을 하지 마라

  • 한 단어를 두가지 목적으로 사용하지 마라
    ex)
    add(int x, int y): x와 y의 합을 구하는 함수
    add(int[] x, int y): x 배열에 y를 추가하는 함수 => insert, append로 이름을 변경하는 것이 좋다.
  • 코드를 최대한 이해하기 쉽게 짜야한다.
    • 대충 훑어봐도 이해할 코드를 작성해야한다.

해법 영역에서 가져온 이름을 사용하라

  • 코드를 읽는 사람도 프로그래머이다.
  • 전산 용어, 알고리즘 이름, 패턴 이름, 수학 용어 등 사용해도 괜찮다.

문제 영역에서 가져온 이름을 사용하라

  • 적절한 프로그래머 용어가 없다면 문제 영역에서 이름을 가져온다.
  • 문제 영역 개념과 관련이 깊은 코드라면, 문제 영역에서 이름을 가져와야 한다.

의미 있는 맥락을 추가하라

  • 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다.
  • 모든 방법이 실패하면, 마지막 수단으로 접두어를 붙인다.
    ex)
    firstName, lastName, street, city, state, …
    해당 변수들은 주소의 일부이다. 하지만, 의미가 잘 드러나지 않는다.
    addr라는 접두어를 추가하면, addrFirstName, addrLastName, … 과 같이 의미가 분명해진다.
    이때, Address라는 클래스를 생성하면 더 좋다.

불필요한 맥락을 없애라

  • 일반적으로 짧은 이름이 긴 이름보다 좋다. 단, 의미가 분명한 경우에 한해서
    이름에 불필요한 맥락(중복/부적절)을 추가하지 않도록 주의한다.