book/Clean Code

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

항성 2022. 8. 27. 16:36
반응형

의도를 분명히 밝혀라

  • 변수는 ‘측정하려는 값’과 ‘단위’를 표현하는 이름이어야 한다.
int elapsedTimeInDays; 
int daysSinceCreation; 
int daysSinceModification; 
int fileAgeInDays;

그릇된 정보를 피해라

  • 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용하지 않는다.
    • ex : ap, aix, sco 등
  • 여러 계정을 그룹으로 묶을 때, 실제 단위가 아니라면 사용하지 않는다.
    • ex : List가 아니라면 accountList라 명명하지 않는다. → accountGroup, accouts 등으로 변환.
  • 서로 흡사한 이름을 사용하지 않는다.
    • ex : 한 모듈에서 XYZControllerForEfficientHandlingOfStrings를 사용하고, 또 다른 모듈이세 XYZControllerForEfficientStorageOfStrings 사용

의미 있게 구분하라

  • 불용어(noise word) 사용을 피한다.
    • ex : 변수 이름에 variable 추가, 표 이름에 table 추가, money라는 변수에 Amount 추가, customer에 Info 추가. → 전부 의미를 중복해서 표현한다.
// 프로그래머가 어떤 함수를 호출할지 어떻게 알까? 
getActiveAccount(); 
getActiveAccounts(); 
getActiveAccountInfo();

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

  • 발음이 어려운 이름을 사용하면 소통이 어렵다
// 잘못된 예시
class DtaRcrd102 {
	//(generate date, year, month, day, hour minute, second)
	private Date genymdhms; 
	private Date modymdhms;
	private final String pszqint = "102";
}

// 수정한 예시
class Customer { 
	private Date generationTimestamp;
	private Date modificationTimestamp;
	private final String recordId = "102"
}

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

  • 문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않음. 검색이 어려움.
  • 이름의 길이는 해당 자료를 사용하는 범위의 크기에 비례해야 한다.
    • ex : MAX_CLASSES_PER_STUDENT는 검색하기 쉽지만, 숫자 7은 검색하기 어렵다.

인코딩을 피하라

  • 이름에 인코딩할 정보는 아주 많다. 유형이나 범위 정보까지 인코딩에 넣으면 그만큼 이름을 해독하기 어려워진다. 개발자에게 부담이 될 수 있음.
    • 헝가리식 표기법
      • 예전에는 유용. 요즘에는 사용 x.
      • 이름의 앞에 타입 정보의 약자를 붙이는 표기법.
    • 멤버변수 접두어
      • 예전에 사용. 요즘에는 사용 x
      • 클래스의 멤버변수에 ‘m_’ 접두어를 붙이는 방법
    • 인터페이스 클래스와 구현 클래스
      • 최근에는 인터페이스는 ShapeFactory로, 구현체는 ShapeFactoryImpl로 표현.
      • 예전에는 인터페이스에 IShapeFactory와 같이 ‘I’ 문자 추가.

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

  • 명료함이 최고. 남들이 이해할 수 있는 이름을 사용하라.

클래스 이름

  • 클래스 이름과 객체 이름은 명사나 명사구가 적합.
    • ex : Customer, WikiPage, Account, AddressParser

메서드 이름

  • 메서드 이름은 동사나 동사구가 적합.
    • ex : postPayment, deletePage, save
  • 접근자, 변경자, 조건자는 javabean 표준에 따라 값 앞에 get, set, is를 붙인다.

기발한 이름은 피하라

  • 특정인만 알아들을 수 있는 이름을 피하고, 모두가 알아들을 수 있는 이름 선택.

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

  • 추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다.
    • ex : 똑같은 메서드를 클래스마다 fetch, retrieve, get 등 서로 다른 이름으로 부르지 않고, 하나의 용어를 계속해서 사용.

말장난을 하지 마라

  • 한 단어를 두 가지 목적으로 사용하지 마라.
    • ex : 같은 맥락이 아닌데도 프로그래머가 ‘일관성’을 고려해서 같은 단어 선택하는 문제.
    • 지금까지 구현한 add 메서드는 모두가 기존 값 두 개를 더하거나, 새로운 값을 만든다고 가정. 새로 작성하는 메서드는 집합에 값 하나를 추가한다. 이 메서드는 기존 add와 맥락이 다르므로 insert나 append라는 이름이 적당.

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

  • 코드를 읽은 사람도 결국 프로그래머. 전산 용어, 알고리즘 이름, 디자인 패턴 이름, 수학 용어등을 사용해도 괜찮다.
  • 프로그래머에게 익숙한 기술 개념은 아주 많다. 기술 개념에는 기술 이름이 적합한 선택.
    • ex : VISITOR 패턴에 친숙한 프로그래머는 AccountVisitor라는 이름을 쉽게 이해.

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

  • 적절한 프로그래머 용어가 없다면 domain 영역에서 이름을 가져온다.

의미 있는 맥락을 추가하라

  • 클래스, 함수 등을 이용해서 하위에 존재하는 변수, 메서드들에 맥락을 부여.
    • 맥락이 불분명한 변수
      • 세 변수 number, verb, pluralModifier가 어떤 걸 표현하는지 불분명
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);
}
  • 맥락이 분명한 함수
    • number, verb, pluralModifier가 message를 표현하는 변수라는 게 명확.
  • 모든 방법이 실패하면 마지막 수단으로 접두어로 맥락 표현.
    • ex: 하나의 method에 firstaName, lastName, street, houserNumber, city, state 라는 변수가 있다면 주소를 표현한다는 것을 이해할 수 있다. 하지만 state라는 변수가 하나만 있다면 해당 변수가 주소에서 사용되는 state라는 것을 표현하기 어려움. 따라서 addrState로 표현.

불필요한 맥락을 없애라

  • Gas Station Delux라는 어플리케이션을 작성한다고 해서 클래스 이름 앞에 GSD를 붙이면 안된다. 자동완성시 G를 누르면 모든 클래스가 출력.
  • 위 방식은 모듈의 재사용 관점에서도 부적절. 재사용하려면 이름을 바꿔야 함. GSDAccountAddress 대신 Address만으로도 충분.

추가 : JavaBean

JavaBean API Specification에 따른 Standard.

아래 세 가지 규칙을 지키는 클래스

  1. 모든 필드는 private이며, getter/setter 메서드를 통해서만 접근이 가능하다.
  2. Argument가 없는 (no-argument) 생성자가 존재한다.
  3. java.io.serializable 인터페이스를 구현한다.
import java.io.Serializable;

public class SomeBean implements Serializable {

    private String beanName;
    private int beanValue;

    public SomeBean(){
        // no-argument constructor
    }

    public String getBeanName() {
        return beanName;
    }

    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }

    public int getBeanValue() {
        return beanValue;
    }

    public void serBeanValue(int beanValue) {
        this.beanValue = beanValue;
    }

}
반응형

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

[Clean Code] 7장, 오류 코드  (0) 2022.08.31
[Clean Code] 6장, 객체와 자료구조  (0) 2022.08.30
[Clean Code] 5장, 형식 맞추기  (0) 2022.08.29
[Clean Code] 4장, 주석  (0) 2022.08.28
[Clean Code] 3장, 함수  (0) 2022.08.27