2장 - 의미 있는 이름

소프트웨어에서 이름은 어디나 쓰인다. 변수, 함수, 인수, 클래스, 소스파일, 디렉터리 등등. 그러므로 이름을 잘 지으면 여러모로 편하다.

기본적인 명명법

클래스 이름

클래스 이름과 객체 이름은 명사명사구가 적합하다. 동사는 지양한다.

메서드 이름

메서드 이름은 동사동사구가 적합하다.

접근자, 변경자, 조건자는 앞에 get, set, is를 붙인다.

const name = employee.getName();
customer.setName('mike');
if (paycheck.isPosted()) ...

메서드는 인수를 설명하는 이름을 사용한다.

// good
const fulcrumPoint: Complex = Complex.FromRealNumber(23.0);

// better - 클래스 생성의 경우 생성자 사용
const fulcrumPoint: Complex = new Complex(23.0);

Rules

의도를 분명히 밝혀라

의도가 분명한 이름은 다음과 같은 질문에 모두 답할 수 있어야 한다.

예시 1)

// bad - 아무 의미도 드러내지 않음
let d;

// good - 측정하려는 값, 단위를 표현함
let elapsedTimeInDays;
let daysSinceCreation;
let daysSinceModification;
let fileAgeInDays;

예시 2)

// bad - 코드의 맥락이 코드 자체에 명시적으로 드러나지 않는다.
function getThem() {
    let list1 = [];
    for (const x of theList) {
        if (x[0] === 4) list1.push(x);
    }
    return list1;
}
// good - 각 개념에 이름이 붙어있어서 역할을 파악하기 쉽다.
function getThem() {
    let flaggedCells = [];
    for (const cell of gameBoard) {
        if (cell[STATUS_VALUE] === FLAGGED) flaggedCells.push(cell);
    }
    return flaggedCells;
}
// better - isFlagged라는 명시적인 함수를 사용해 FLAGGED라는 상수를 감췄다.
function getThem() {
    let flaggedCells = [];
    for (const cell of gameBoard) {
        if (cell.isFlagged()) flaggedCells.push(cell);
    }
    return flaggedCells;
}

그릇된 정보를 피하라

헷갈리게 만들거나, 오해의 소지가 있는 단어 피하기

의미 있게 구분하라

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

프로그래밍은 사회 활동이기 때문에 발음하기 쉬운 이름은 중요하다.

// bad
let genymdhms; // generated-ymd-hms의 약어임은 알겠으나 발음을 알 수 없음
let modymdhms;
const pszqint = "102";

// good
let generationTimeStamp;
let modificationTimeStamp;
const recordId = "102";

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

인코딩을 피하라

변수명에 굳이 유형이나 범위 정보까지 인코딩하지 말자.

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

기발한 이름은 피하라

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

말 장난을 하지 마라

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

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

의미 있는 맥락을 추가하라

변수를 클래스, 함수, 이름 공간(Namespace)에 넣어 맥락을 부여한다. 최후의 수단으로 접두어를 붙인다.

// bad
function printGuessStatistics(candidate, count) {
    let number;
    let verb;
    let pluralModifier;
    if (count === 0) {
        number = "no";
        verb = "are";
        pluralModifier = "s";
    } else if (count === 1) {
        number = "1";
        verb = "is";
        pluralModifier = "";
    } else {
        number = count.toString();
        verb = "are";
        pluralModifier = "s";
    }
    const guessMessage = `There ${verb} ${number} ${candidate}${pluralModifier}`;
    console.log(guessMessage);
}
// good
class GuessStatisticsMessage {
    make(candidate, count) {
        createPluralDependentMessageParts(this.count);
        return `There ${this.verb} ${this.number} ${this.candidate}${this.pluralModifier}`;
    }

    createPluralDependentMessageParts(count) {
        if (count === 0) {
            thereAreNoLetters();
        } else if (count === 1) {
            thereIsOneLetter();
        } else {
            thereAreManyLetters(count);
        }
    }

    thereAreManyLetters(count) {
        this.number = count.toString();
        this.verb = "are";
        this.pluralModifier = "s";
    }

    thereIsOneLetter() {
        this.number = "1";
        this.verb = "is";
        this.pluralModifier = "";
    }

    thereAreNoLetters() {
        this.number = "no";
        this.verb = "are";
        this.pluralModifier = "s";
    }
}

불필요한 맥락을 없애라

마치면서

좋은 이름을 선택하는 것은 어렵다.
설명 능력이 뛰어나야 하고 문화적인 배경이 같아야 하기 때문이다.
사람들이 이름을 바꾸지 않으려는 이유 하나는 다른 개발자가 반대할까 두려워서다.
그러나 코드를 개선하려는 노력을 중단해서는 안되며, 우리는 쉽게 읽히는 코드를 짜는데 집중해야한다.