Chapter 04. 올바르게 명명하기

Yeseong31·2023년 8월 23일
0

자바 코딩의 기술

목록 보기
4/8

컴퓨터 과학에서 어려운 문제는 딱 두 가지,
캐시 무효화(cache invalidation)명명(naming)이다. - 필 칼튼


자바 명명 규칙 사용하기

class Rover {

	static final double WALKING_SPEED = 3;

	final string serialNumber;
	double milesPerHour;

	Rover(String SerialNumber) {
		this.serialNumber = SerialNumber;
	}

	void drive() {
		milesPerHour = WALKING_SPEED;
	}

	void stop() {
		milesPerHour = 0;
	}
}

자바 코드 규칙은 1997년부터 있었다.
이 규칙은 이름을 비롯해 자바 코드를 서식화하는 실질적 표준이다.

  • 클래스, 인터페이스, enumCamelCase로 작성한다.
  • 상수는 CAPITAL_SNAKE_CASE로 작성한다.
  • 메서드, 필드 매개변수, 변수는 첫 글자가 소문자로 시작하는 변형된 camelCase로 작성한다.
  • 메서드는 동사로 명명하거나 is, has, save, get, set 등과 같이 동사로 시작해야 한다.


프레임워크에는 Getter/Setter 규칙 적용

class Member {

	private String name;
	private boolean status;

	public Member() {
	}

	public Member(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public boolean isStatus() {
		return status;
	}

	public void setStatus(boolean status) {
		this.status = status;
	}
}

GetterSetter는 표준화가 잘 되어 있어서 여러 프레임워크에서 대부분 따르고 있다.
이에 GetterSetter만의 명세인 자바 빈 명세도 따로 존재한다.

  • 필드의 한정자private으로, GetterSetterpublic으로 작성한다.
  • 기본 생성자로 빈 인스턴스를 만들고, Setter로 필드에 값을 할당한다.
  • 기본적으로 GetterSetter의 이름은 getXxx, setXxx로 한다.
    • 다만, boolean 타입의 필드는 isXxx로 이름을 붙인다.

Setter무분별하게 사용하면 안 된다.
Setter는 의도를 쉽게 파악하기 어렵고, 일관성을 지키는 것을 힘들게 만든다.



한 글자로 명명하지 않기

한 글자 이름에는 이유가 있을 수 없다.

  • 변수명이 계속 반복되고 코드 맥락에 어긋나면 읽기 점점 어려워진다.
  • 그래서 변수명에는 의미가 있어야 하고, 이를 위해서는 한 글자 변수명을 지양해야 한다.

코드가 비효율적이게 될까 봐 걱정할 수 있는데,
어차피 컴파일러는 컴파일 타임에 이름을 바이트코드로 대체해 버리므로 상관없다.



축약 쓰지 않기

자신만의 축약어는 코드의 의미를 파악하는 데 큰 걸림돌이 될 수 있다.

  • 흔히 사용하는 축약만 사용하고, 그 외에는 전체 이름을 사용하자.


무의미한 용어 쓰지 않기

  • 다음의 예제를 살펴보자.
class MainSpaceShipManager {

    AbstractRocketPropulsionEngine abstractRocketPropulsionEngine;
    INavigationController navigationController;
    boolean turboEnabledFlag;

    void navigateSpaceShipTo(PlanetInfo planetInfo) {
        RouteData data = navigationController.calculateRouteData(planetInfo);
        LogHelper.logRouteData(data);
        abstractRocketPropulsionEngine.invokeTask(data, turboEnabledFlag);
    }
}
  • 위 예제는 축약을 전혀 쓰지 않았지만 그렇다고 변수명의 형태를 잘 지은 것도 아니다.
  • 어찌 보면 의미 없는 단어의 수만 늘리고 있다고 볼 수 있다.

간결성과 명명: 끝없는 투쟁

간결한 명명이 항상 미덕인 것은 아니다.
알아 들을 수 없는 축약어 대신 길지만 의미 있는 서술적인 이름이 낫다.
이름은 쓸 일보다 읽힐 일이 훨씬 많기 때문에 명확함을 추구하는 것이 좋다.

class spaceShip {
    Engine engine;
    Navigator navigatonr;
    boolean turboEnabled;

    void navigateTo(Planet destination) {
        Route route = navigator.calculateRouteTo(destination);
        Logger.log(route);
        engine.follow(route, turboEnabled);
    }
}
  • 위 예제는 이전의 코드와 비교했을 때 코드의 양을 상당히 줄였다.
  • 먼저 변수명에서 전형적으로 무의미한 용어들(flag, info, data 등)을 제거했다.
  • 또한 타입명을 읽을 때 해당 변수가 어떤 타입인지 명시한 부분을 제거했다.
  • 클래스명만 보아도 이미 멤버에 대한 정보를 얻을 수 있으므로 반복적인 명명도 제거했다.

Spring 프레임워크에는 유명한 클래스명이 하나 있다.
장미는 붉고 잎사귀는 푸른데 유독 자바에만 AbstractSingletonProxyFactryBean 클래스가 있다.



도메인 용어 사용하기

  • 다음의 예제를 살펴보자.

class Person {
    String lastName;
    String role;
    int travels;
    LocalDate employedSince;

    String serializeAsLine() {
        return String.join(",", 
                Arrays.asList(lastName,
                        role,
                        String.valueOf(travels),
                        String.valueOf(employedSince))
        );
    }
}
  • 위 예제는 어떤 사람의 성씨, 직무, 출장 횟수, 고용일을 나타내는 클래스이다.
  • 일단 전체적으로 코드가 포괄적인 의미를 가지지만, 그 이유는 알 수 없다.
    • 왜 성씨만 저장하는가?
    • 왜 출장 횟수를 기록할까?
    • serializeAsLine() 메서드는 어떤 형식을 다루는가?

클래스나 패키지처럼 범위가 넓은 이름은 메서드 내 변수 같은, 범위가 좁은 이름보다 훨씬 많이 읽힌다.
따라서 중요한 이름에는 더 많은 노력을 쏟아야 한다.

class Astronaut {
    String tagName;
    String rank;
    int missions;
    LocalDate activeDutySince;

    String toCSV() {
        return String.join(",", 
                Arrays.asList(tagName,
                       rank,
                       String.valueOf(missions),
                       String.valueOf(activeDutySince))
        );
    }
}
  • 위 예제는 이전의 코드를 클래스의 사용 목적과 맥락을 고려하여 속성의 이름을 변경한 형태이다.
  • 이제 클래스 이름만 보더라도, 이 클래스가 무슨 역할을 하는지 알 수 있다.
  • 또한 메서드의 이름을 toCSV()로 변경하여 메서드의 의도를 더 확실히 알 수 있게 되었다.

가능하면 코드 내 이름은 해당 도메인에 맞게 짓고 포괄적인 명칭은 피하자.

완벽한 명명은 불가능하다. 더 나은 이름이 떠오를 때까지 항상 리팩터링하자.


이 장의 내용은 [자바 코딩의 기술: 똑똑하게 코딩하는 법]의 4장 내용을 정리한 것입니다.

profile
역시 개발자는 알아야 할 게 많다.

0개의 댓글

관련 채용 정보