2장 의미 있는 이름

❝코드는 남을 위해서 읽기 좋게 쓰는 것❞

❝이름은 짧을수록 좋지만, 짧은 대신 의미가 선명해야 한다. 길어도 되는 이유는, 코드보다 주석보다 이름이 더 중요하기 때문이다.❞


좋은 이름을 위한 원칙

원칙 1: 읽는 사람이 쉽게 이해할 수 있어야 한다

👉 “이름만 보고 용도를 유추할 수 있어야 한다.”

  1. 의도를 분명히 밝혀라

    | 나쁜 예 | 좋은 예 | | — | — | | int d; | int daysSinceCreation; |

    • 변수명, 함수명, 클래스가 무엇을 하는지 정확하게 드러나야 한다.
      • 존재 이유
      • 수행 기능
      • 사용 방법
  2. 의미 있게 구분하라

    | 나쁜 예 | 좋은 예 | | — | — | | state | addressState, userState |

    • 의미가 모호한 단어는 맥락에 따라 명확히 구분해야 한다.
    • 이름이 달라야 한다면 의미도 달라야 한다.
      • 불용어를 사용한 이름은 아무런 정보도 제공하지 못한다.
        • ex) a1, a2, a3 … an
      • 읽는 사람이 알 수 있도록 구분되는 의미가 담겨야 한다.
        • accountData vs account
  3. 검색 가능한 이름을 써라

    | 나쁜 예 | 좋은 예 | | — | — | | int e; | int employeeCount; | | 5 | MAX_CLASSES |

    • 이름이 짧거나 모호한 변수, 상수는 코드 검색이 매우 어렵다.

원칙 2: 그릇된 정보를 피하라

// Set인데 이름은 List라 혼란을 유발
Set<Account> accountList = new HashSet<>();
  • 이름이 데이터의 구조나 역할과 다르면 오해를 일으킨다.
    • List라는 이름을 붙였는데 실제 자료형이 Set이라면 읽는 사람은 중복이 허용된다고 착각할 수 있다.

| 나쁜 예 | 좋은 예 | | | — | — | — | | userInfouserData | userRequestuserResponse | 서로 다른 역할인데 이름만 보면 유사하게 느껴짐 | | dataManagerdataController | cacheManagerhttpController | 실제 책임이 다르다면 이름도 구분 지어야 함 | | processHandlerprocessManager | taskSchedulertaskRunner | 추상적인 이름은 구체적인 역할로 바꾸자 |

  • 비슷하지만 다른 역할을 하는 이름에는 서로 확실히 다른 이름을 붙여야 한다.

| 나쁜 예 | 좋은 예 | | | — | — | — | | getUser()fetchMember() | getUser()getMember() | 동작은 동일한데 표현만 다르면 통일성 떨어짐 | | saveUser()storeMember() | saveUser()saveMember() | 동사는 하나로 통일해주는 게 좋음 | | calculateSum()computeAverage() | calculateSum()calculateAverage() | 같은 역할이면 접두사도 일치하는게 좋음 |

  • 반대로, 역할이나 용도가 비슷하다면 이름도 일관성 있게 유지해야 혼란을 줄일 수 있다.

❗이름에 잘못된 정보나 혼동을 줄 수 있는 표현은 피한다.

  • 헷갈리기 쉬운 철자는 피하는 것이 좋다.
    • l(소문자 L)과 1(숫자 1)
    • O(대문자 알파벳 O)와 0(숫자 0)
  • 잘못된 암시를 주는 단어도 혼동을 야기한다.
    • accountList → 실제는 Set<Account>
    • isAvailable → 실은 항상 false인 플래그
  • 복수형/단수형 이름의 오용도 주의
    • users가 User 하나만 담고 있는 경우 혼동을 준다.

원칙 3: 발음하기 쉬운 이름을 써라

| 나쁜 예 | 좋은 예 | | — | — | | genymdhms | generationTimestamp |

  • 말로 설명하기 어려운 이름은 피한다.
  • 뉴비도 이해하기 쉽도록 만든다.

원칙 4: 인코딩을 피하라(불필요한 접두어를 제거)

| 나쁜 예 | 좋은 예 | | — | — | | class CProductInfo | class Product | | strNameiCount | name, count |

  • 클래스명, 변수명에 헝가리안 표기법(C, M, S 등) 같은 접두어를 붙이면 오히려 가독성을 해친다.

원칙 5: 명사/동사 구분을 명확히 하라

| 구분 | 예시 | | — | — | | 클래스 (명사) | User, Invoice, Product | | 함수 (동사) | calculateTotal(), saveUser() |

  • 역할에 맞게 자연스러운 문장처럼 읽히게 구성한다.
    • 클래스/변수는 명사, 함수는 동사로 이름을 짓는다.
  • 역할에 따라 이름 패턴을 정하면 자연스러운 코드 흐름을 만든다.
  • 생성자를 중복정의할 때는 정적 팩토리 메서드를 사용한다.

원칙 6: 한 개념에 한 단어를 사용하라

| 나쁜 예 | 좋은 예 | | | — | — | — | | fetchData(), retrieveUser() | getData(), getUser() | 같은 역할이면 동사를 통일해 혼란을 줄인다 | |

  • 같은 동작에는 같은 표현을 반복해서 사용한다.
    • 예측 가능한 코드가 되고, 학습 비용이 줄어든다.
    • 주석을 보지 않아도 프로그래머가 올바른 메서드를 선택할 수 있다.