[Clean Code] 2장 의미 있는 이름

ASk·2021년 12월 30일
0

Clean Code

목록 보기
2/17
post-thumbnail

의도를 분명히 밝혀라

  • 의도가 분명한 이름은 정말로 중요하다.
  • 존재이유, 수행기능, 사용방법 등이 변수, 함수, 클래스의 이름에 분명히 드러나야 한다. (주석이 필요하지 않을 정도로)
  • 예시 1
    • Bad
      • int d; // elapsed time in days
    • Good
      • int elapsedTimeInDays;
      • int daysSinceCreation;
      • int daysSinceModification;
      • int fileAgeInDays;
  • 예시 2
// Bad
public List<int[]> getThem() {
  List<int[]> list1 = new ArrayList<int[]>();
  for (int[] x : theList) {
    if (x[0] == 4) {
      list1.add(x);
    }
  }
  return list1;
}

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

그릇된 정보를 피하라

  • 코드에 그릇된 단서를 남겨서는 안된다, 코드의 의미를 흐리기 때문.
  • 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용해도 안된다.
  • 개발자에게는 특수한 의미를 가지는 단어(List 등)는 실제 컨테이너가 List가 아닌 이상 accountList와 같이 변수명에 붙이지 말자.
  • 차라리 accountGroup, bunchOfAccounts, accounts 등으로 명명하자.
  • 서로 흡사한 이름을 사용하지 않도록 주의한다.
  • 일관성이 떨어지는 표기법은 그릇된 정보다.

의미 있게 구분하라 (불용어 -noise word- 를 쓰지 말자)

  • 이름이 달라야 한다면 의미도 달라져야 한다.
  • 연속적인 숫자를 덧붙인 이름(a1, a2, ..., aN) 은 저자의 의도가 전혀 드러나지 않는다.
  • 예시 1
// Bad
public static void copyChar(char[] a1, char[] a2)

// Good
public static void copyChar(char[] source, char[] destination)
  • Info, Data, a, an, the 도 의미가 불분명한 불용어 이다.
  • a, the 와 같은 접두어를 사용하지 말라는 것이 아닌, zork 라는 변수가 있다고 theZork 라고 지으면 안된다.
  • 불용어는 중복이다. ex. 변수 이름에 variable, 표이름에 table
  • 읽는 사람이 차이를 알도록 이름을 지어야한다.
  • 예시 2
    • Name VS NameString
    • money VS moneyAmount
    • customer VS customerObject
    • message VS theMessage

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

  • 프로그래밍은 사회활동이다. 발음이 쉬운 이름을 사용해야 커뮤니케이션에 더 도움된다.
  • 예시 1
// Bad
class DtaRcrd102 {
    private Date genymdhms;
    private Date modymdhms;
    private final String pszqint = "102";
    /* ... */
};

// Good
class Customer {
    private Date generationTimestamp;
    private Date modificationTimestamp;
    private final String recordId = "102";
    /* ... */
};

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

  • 문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다.
  • 검색하기 쉬운이름이 상수보다 좋다.
  • 이름 길이는 범위 크기에 비례해야 한다.

인코딩을 피하라 (변수에 부가 정보를 덧붙여 표기하는 것을 뜻함.)

  • 유형이나 범위 정보까지 인코딩에 넣으면 그만큼 이름 해독이 어려워진다.
  • 인코딩한 이름은 거의 발음하기 어려우며 오타가 생기기도 쉽다.

헝가리식 표기법

  • 과거 컴파일러가 타입을 점검하지 않을 경우 변수에 타입을 나타냄
  • 최근 컴파일러, IDE 가 타입을 알고 있으므로 사용하지 않음.

멤버 변수 접두어

  • m_ 등의 접두어를 붙일 필요가 없다.

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

  • 때로는 인코딩이 필요할때도 있다.
  • 인터페이스 클래스와 구현 클래스를 나눠야 한다면 구현 클래스의 이름에 정보를 인코딩하자.
  • -인터페이스구현체
    OShapeFactoryShapeFactoryImpl
    XIShapeFactoryShapeFactory

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

  • 독자가 머리속으로 한번 더 생각해 변환해야 할만한 변수명을 쓰지 마라.
  • 전문가 프로그래머는 명료함이 최고라는 사실을 이해한다.
  • 전문가 프로그래머는 자신의 능력을 좋은 방향으로 사용해 남들이 이해하는 코드를 작성한다.

클래스 이름

  • 클래스이름과 객체 이름은 명사나 명사구가 적합하다.(Customer, WikiPage, Account, AddressParser)
  • Manager, Processor, Data, Info 와 같은 단어는 피하자
  • 동사는 사용하지 않는다.

메서드 이름

  • 동사 혹은 동사구를 사용하라.(postPayment, deletePayment, deletePage, save 등)
  • 접근자, 변경자, 조건자는 get, set, is로 시작하자. (추가: should, has 등도 가능)
  • 생성자를 중복정의(overload) 할 경우 정적 팩토리 메서드를 사용한다.
  • 예시 1
// BAD  
Complex fulcrumPoint = new Complex(23.0);

// GOOD
Complex fulcrumPoint = Complex.FromRealNumber(23.0);
  • 생성자 사용을 제한하려면 해당 생성자를 private 으로 선언한다.

기발한 이름은 피하라

  • 재미난 이름보다 명료한 이름을 선택하라.
  • 특정 문화에서만 사용되는 재미있는 이름보다 의도를 분명히 표현하는 이름을 사용하라
    • HolyHandGrenade → DeleteItems
    • whack() → kill()
  • 의도를 분명하고 솔직하게 표현하라.

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

  • 추상적인 개념 하나에 단어 하나를 사용하자.
  • 똑같은 메서드를 클래스마다 제각각 부르면 혼란스럽다.
  • 예시 1
    • fetch, retrieve, get
    • controller, manager, driver
  • 이름이 다르면 독자는 당연히 클래스도 다르고 타입도 다르리라 생각한다.
  • 일관성 있는 어휘는 코드를 사용할 프로그래머가 반갑게 여길 선물이다.

말장난을 하지 마라

  • 한 단어를 두 가지 목적으로 사용하지 말자
  • 같은 맥락이 아닌데도 일관성을 고려해 이름을 같게 하면 안된다.
  • 프로그래머는 코드를 최대한 이해하기 쉽게 짜야한다.
  • 집중적인 탐구나 필요한 코드가 아니라 대충 훝어봐도 이해할 코드 작성이 목표다.

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

  • 코드를 읽는사람도 프로그래머라는 사실을 명심한다.
  • 전산용어, 알고리즘 이름, 패턴 이름, 수학 용어 등은 사용해도 괜찮다.
  • 개발자라면 당연히 알고 있을 JobQueue, AccountVisitor(Visitor pattern) 등 기술 개념에는 기술이름이 가장 적합한 선택이다.

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

  • 적절한 프로그래머 용어가 없거나 문제영역과 관련이 깊은 용어의 경우 문제 영역 용어를 사용하자.
  • 우수한 프로그래머와 설계자라면 해법 영역과, 문제영역을 구분할 줄 알아야 한다.

의미 있는 맥락을 추가하라

  • 스스로 의미가 분명한 이름도 있지만 대다수 그렇지 못하다.
  • 따라서 클래스, 함수, 이름 공간에 넣어 맥락을 부여한다.
  • 모든 방법이 실패하면 마지막 수단으로 접두어를 붙인다.
  • 예시 1
    • firstName, lastName, state -> addrFirstName, addrLastName, addrState
  • 예시 2, 클래스에 변수를 넣어 맥락을 부여.
// Bad
private void printGuessStatistics(char candidate, int count){
  String number;
  String verb;
  String pluralModifier;
  ...
}

// Good
public class GuessStatisticsMessage {
  private String number;
  private String verb;
  private String pluralModifier;
  ...
}

불필요한 맥락을 없애라

  • Gas Station Deluxe 이라는 어플리케이션을 작성한다고 해서 클래스 이름의 앞에 GSD를 붙이지는 말자.
  • IDE에서 G를 입력하고 자동완성을 누를 경우 모든 클래스가 나타나는 등 효율적이지 못하다.
  • 일반적으로 짧은 이름이 긴이름보다 좋다. 단, 의미가 분명한 경우에 한해서
  • 이름에 불필요한 맥락을 추가하지 않도록 주의해야한다.
  • accountAddress, customerAddress 는 Address 클래스 인스턴스로는 좋은이름이나 클래스 이름으론 부적합하다.

결론

  • 좋은 이름을 선택하려면 설명 능력이 뛰어나야 하고 문화적인 배경이 같아야한다. 이것이 제일 어렵다.
  • 이름을 바꾸지 않으려는 이유 하나는 다른 개발자가 반대할까 두려워서다.
  • 여느 코드개선 노력과 마찬가치로 이름 역시 나름대로 바꿨다가 누군가 질책할지도 모르지만 그렇다고 코드, 이름을 개선하려는 노력을 중단해서는 안된다.
  • 다른 사람이 짠 코드를 손본다면 문제해결 목적으로 이름을 개선하라.

이름 개선을 두려워 하지 말고 '자연스러운 문장이나 문단처럼 읽히는 코드' 가 될수 있도록 고민하고 개선해야한다.

profile
Backend Developer

0개의 댓글