2. 의미 있는 이름

소울치킨·2022년 4월 24일
0
post-thumbnail
  • 변수에도, 함수에도, 인수, 클래스, 패키지, 디렉토리까지 다 이름이 붙는다. 이름을 잘 지으면 여러모로 편리하다.

의도를 분명히 밝혀라

  • 정말로 중요
  • 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.
  • 이름은 다음과같은 굵직한 질문에 답해야한다. 따로 주석이 필요하다면 의도를 분명히 드러내지 못한 것이다.
    1. 변수(혹은 함수나 클래스)의 존재 이유는?
    2. 수행 기능은?
    3. 사용 방법은?
// 잘못된 예
int d; // 경과 시간 (단위 : 날짜)

// 좋은 예
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;

코드 읽어보기

public List<int[]> getThem() {
    List<int[]> list1 = new ArrayList<int[]>();
    
    for (int[] x : theList)
        if (x[0] == 4)
            list1.add(x);
    return list1;
}

코드가 하는 일을 짐작하기 어렵다.
복잡한 문장도, 공백 들여쓰기도 적당하다. 변수 상수도 몇 개 안된다.
화려한 클래스나 다형 메서드도 없다.
문제는 코드의 단순성이 아니라 코드의 함축성이다.
코드 맥락이 코드 자체에 명시적으로 드러나지 않는다,.

  1. theList에 무엇이 들어가 있는가?
  2. theList에서 0번째 값이 어째서 중요한가?
  3. 값 4는 무슨 의미인가?
  4. 함수가 반환하는 리스트 list1을 어떻게 사용하는가?

지뢰찾기를 만드는 문제라면?

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

}

- 게임에서 각 칸은 단순 배열로 표현한다.
- 0번째 값은 칸 상태를 뜻한다.
- 값 4는 깃발이 꽂힌 상태를 가리킨다.

> 한걸음 더 나아가보기
> - int 배열을 사용하는 대신, 칸을 간단한 클래스로 만들기
> - isFlagged라는 좀 더 명시적인 함수를 사용해 FLAGGED라는 상수를 감추기

```java
public List<Cell> getFlaggedCells() {
    List<Cell> flaggedCells = new ArrayList<Cell>();

    for (Cell cell : gameBoard)
        if (isFlagged())
            flaggedCells.add(cell);
    return flaggedCells;
}

그릇된 정보를 피하라

  • 코드에 그릇된 단서를 남겨 코드 의미를 흐리면 안된다. 다른 의미가 있는 단어는 쓰지 않는다.
  • 서로 흡사한 이름은 사용하지 않는다.
  • 유사한 개념은 유사한 표기법을 사용한다. 이것도 정보다. 일관성이 떨어진 표기법은 그릇된 표기법이다.
  • 빗변을 나타내려고 만든 변수명 hp(hypotenuse)는 노트북일지도...?
  • accountList 보다는 accountGroup, bunchOfAccount가 났다.
  • XYZControllerForEfficientHandlingOfStrings 와 XYZControllerForEfficientStorageOfStrings 같은 두 비슷한 단어를 쓰지 않는다.

의미 있게 구분하라

  • 굴러가게만 하는 코드는 문제를 일으킨다.
  • 연속된 숫자를 덧붙이거나 불용어를 추가하는 방식은 적절하지 않다.
  • 읽는 사람이 차이를 알 수 있도록 이름을 짓자.
    • a1, a2, a3 ... an 은 안좋다.
    • Product라는 클래스가 있는데 ProductInfo, ProductData 클래스를 쓰는건 의미가 불분명하다.
    • 고객 급여를 알고 싶다면 Customer 클래스와 CustomerObject 클래스 중 어떤 것을 뒤져야할지 모른다.
    • a, an, the도 마찬가지로 불용어다.
    • 변수 이름에 variable, 표에 table같은 것 쓰지 않는다.

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

  • genymdhms (generate date, year, month, day, hour, minute, second 라는 뜻)같은 변수명을 쓰는 사례는 없어야한다.

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

  • 이름의 길이는 범위 크기에 비례한다. 저자는 간단한 메서드에서 로컬 변수만 한 문자를 사용한다고 한다.
  • 평일이 5일이다. 그렇다고 코드에서 평일을 사용한 라인을 찾기 위해 5를 검색하면 힘들다.
    int WORK_DAYS_PER_WEEK = 5를 사용하자.
  • 변수 이름에 숫자, e, n같은 간단하고 자주쓰이는 것은 쓰지 않는다.

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

  • 문자 하나만 사용하는 변수 이름은 사용하지 마라
    • 루프에서 i, j, k는 루프 범위가 작고 다른 이름과 충돌하지 않을 때만 괜찮다.
      (l은 절대 안됨)
  • 명료함이 최고다.

이름

  • 클래스 : 클래스, 객체 이름은 명사나 명사구. (Customer, WikiPage, Account ...)
    • Manager, Processer, Data 등과 같은 단어는 피하고 동사는 사용하지 않느낟.
  • 매서드 : 동사나 동사구. (postPayment, deletePage, save ...)
    • javabean 표준에 따라 접근자, 변경자, 조건자는 get, set, is를 붙인다.

기발한 이름은 피하라

  • 말장난으로 재밌는 이름을 짓지 말고 명료한 이름을 선택하라.

한 개념에 한 단어만 사용

  • 추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다.
    똑같은 메서드를 클래스마다 fetch, retrieve, get으로 제각각 부르지 않는다.

말장난 금지

  • 한 단어를 두 가지 목적으로 사용하지 않는다. '일관성'을 고려해야한다.
  • 숫자를 더할때도 add, list에 요소를 추가할 때도 add... ㄴㄴ;

의미있는 맥락 추가

  • 스스로 의미가 분명한 이름이 많지 않다. 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다.
  • 모든 방법이 실패하면 마지막에 접두어를 넣는다.

    변수 이름이 firstName, lastName, houseNumber, street, city, state 등이 있다면 코드가 있는 부분이 주소를 의미한다는 사실을 쉽게 알 수 있다.

불필요한 맥락을 없애라

  • 고급 휘발유 충전소 (Gas Station Deluxe) 어플리케이션에 클래스 이름을 GSD로 시작하는 것은 바람직하지 못하다. G를 입력하고 자동완성키를 누르면 모든 클래스가 열거된다.

마치면서

  • 암기는 도구에게 맡기고, 우리는 문장, 문단처럼 읽히는 코드 아니면 적어도 표나 자료 구조처럼 읽히는 코드를 짜는 데만 집중해야한다.
profile
소울치킨입니다

0개의 댓글