의도를 분명히 밝혀라

다음과 같은 질문에 답할 수 있어야 한다.

  • 변수(or 함수, 클래스)의 존재 이유는?
  • 수행 기능은?
  • 사용 방법은?

Good

  • int elapsedTimeInDays;
  • int daysSinceCreation;
  • int daysSinceModification;
  • int fileAgeInDays;

그릇된 정보를 피하라

  • 널리 쓰이는 의미가 있는 단어는 사용하지 말자.
  • 서로 흡사한 이름을 사용하지 않도록 주의한다.
  • 유사한 개념은 유사한 표기법을 사용한다.

의미 있게 구분하라

  • Info, Data와 같은 불용어를 붙이지 말자.
  • 읽는 사람이 차이를 알도록 이름을 지어라.

Bad

  • getActiveAccount(), getActiveAccounts(), getActiveAccountInfo()

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

Bad

  • Date genymdhms

Good

  • Date generationTimestamp

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

  • 이름의 길이는 범위의 크기에 비례해야 한다.

인코딩을 피하라

  • 멤버 변수에 접두어를 붙이지 말자.
  • 클래스와 함수는 접두어가 필요없을 정도로 작아야 마땅하다.
  • 인터페이스 클래스 이름과 구현 클래스 이름 중 하나를 인코딩해야 한다면?
    • 구현 클래스 이름을 택하자.

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

  • 독자가 코드를 읽으면서 변수 이름을 자신이 아는 이름으로 변환해야 한다?
    • 그 변수 이름은 바람직하지 못한 것이다.
  • 명료함이 최고다.

클래스 이름

  • 명사, 명사구가 적합하다.
  • Manager, Processor, Data, Info 등과 같은 단어는 피하자.
  • 동사를 사용하지 말자.

메서드 이름

  • 동사, 동사구가 적합하다.
  • 접근자, 변경자, 조건자는 get, set, is를 붙인다.
  • 생성자를 중복정의할 때는 정적 팩토리 메서드를 사용한다.
    • 메서드는 인수를 설명하는 이름을 사용한다.

기발한 이름은 피하라

  • 특정 문화에서만 사용하는 농담은 피하자.
  • 의도를 분명하고 솔직하게 표현하라.

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

  • 추상적인 개념에 단어 하나를 선택해 계속 사용하자.

Bad

  • fetch, retrieve, get
  • controller, manager, driver
  • 위처럼 제각각으로 부르면 혼란스럽다.

말장난을 하지 마라

  • 다른 개념에 같은 단어를 사용하지 말자.
  • 맥락에 따라 add라는 단어보다 insert, append라는 이름이 적당할 수도 있다.

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

  • 전산용어, 알고리즘 이름, 패턴 이름, 수학 용어 등은 사용하자.

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

  • 적절한 프로그래머 용어가 없다면 문제 영역에서 이름을 가져온다.
  • 해법 영역과 문제 영역을 구분할 줄 알아야 한다.

의미 있는 맥락을 추가하라

  • 클래스, 함수, 이름 공간(namespace)에 넣어 맥락을 부여하자.
  • 맥락을 개선하면 함수를 쪼개기가 쉬워지므로 알고리즘도 좀 더 명확해진다.
  • 모든 방법이 실패하면 마지막 수단으로 접두어를 붙인다.

Bad

private void printGuessStatistics(char candidate, int count) {
    String number;
    String verb;
    String pluralModifier;
    if (count == 0) {  
        number = "no";  
        verb = "are";  
        pluralModifier = "s";  
    }  else if (count == 1) {
        number = "1";  
        verb = "is";  
        pluralModifier = "";  
    }  else {
        number = Integer.toString(count);  
        verb = "are";  
        pluralModifier = "s";  
    }
    String guessMessage = String.format("There %s %s %s%s", verb, number, candidate, pluralModifier );

    print(guessMessage);
}

Good

public class GuessStatisticsMessage {
    private String number;
    private String verb;
    private String pluralModifier;

    public String make(char candidate, int count) {
        createPluralDependentMessageParts(count);
        return String.format("There %s %s %s%s", verb, number, candidate, pluralModifier );
    }

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

    private void thereAreManyLetters(int count) {
        number = Integer.toString(count);
        verb = "are";
        pluralModifier = "s";
    }

    private void thereIsOneLetter() {
        number = "1";
        verb = "is";
        pluralModifier = "";
    }

    private void thereAreNoLetters() {
        number = "no";
        verb = "are";
        pluralModifier = "s";
    }
}
  • 함수를 작은 조각으로 쪼개고자 GuessStatisticsMessage라는 클래스를 만든 후 세 변수를 클래스에 넣었다.
  • 이제 세 변수는 맥락이 분명해진다.

불필요한 맥락을 없애라

  • Address는 클래스 이름으로 적합하다.
  • accountAddress, customerAddress는 클래스 이름으로 적합하지 않다.
  • 포트 주소, MAC 주소, 웹 주소를 구분해야 한다면 PostalAddress, MAC, URI의 이름이 괜찮다.

'Clean Code' 카테고리의 다른 글

[Clean Code] 경계  (0) 2020.09.03
[Clean Code] 오류 처리  (0) 2020.09.03
[Clean Code] 객체와 자료구조  (0) 2020.09.03
[Clean Code] 형식 맞추기  (0) 2020.09.03
[Clean Code] 함수  (0) 2020.09.03

+ 따끈한 최근 게시물