클린 코드 읽기 2 - 의미 있는 이름

toastedEevee·2024년 6월 25일
0

클린 코드 읽기

목록 보기
2/7

의도를 분명히 밝혀라

변수나 함수 그리고 클래스 이름은 다음과 같은 굵직한 질문에 모두 답해야 한다.

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

따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 말이다.
의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워진다.

코드의 맥락이 코드 자체에 명시적으로 드러나게 하기

아래 코드는 무슨 일을 하는지 짐작하기 어렵다.

public List<int[]> getThem() {
	List<int[]> list1 = new ArrayList<int[]>();
	for (int[] x : theList)
		if (x[0] == 4)
			list1.add(x);
	return list1;
}

위 코드의 문제는 함축성이다. 독자가 앞 뒤 전체 코드의 맥락을 알고 있어야만 이해할 수 있다.

이 코드를 이용해서 지뢰찾기 게임을 만든다고 가정하고 수정한다면?

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

게임판에서 각 칸은 단순 배열로 표현한다. 배열에서 0번째 값은 칸 상태를 뜻한다. 값 4는 깃발이 꽂힌 상태를 가리킨다. 이렇게 각 개념에 이름만 붙여도 코드를 이해하기 훨씬 수월해진다.

바로 이것이 좋은 이름이 주는 위력이다.

그릇된 정보를 피하라

그릇된 단서는 코드 의미를 흐린다. 이미 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용해도 안된다.

서로 흡사한 이름을 사용하지 않도록 주의한다.

유사한 개념은 유사한 표기법을 사용한다. 일관성이 떨어지는 표기법은 그릇된 정보이다.

의미 있게 구분하라

컴파일러를 통과할지라도 연속된 숫자를 덧붙이거나 불용어(noise word)를 추가하는 방식을 적절하지 못하다. 이름이 달라야 한다면 의미도 달라져야 한다.

ProductInfo와 ProductData의 차이가 뭐라고 느껴지는가? a, an, the와 같은 불용어는 중복에 불과하다. 변수 이름에 variable, 표이름에 table 이라는 단어 또한 마찬가지로 금물이다.

읽는 사람이 차이를 알도록 이름을 지어야 한다.

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

사람들은 단어에 능숙하다.

발음하기 어려운 이름은 토론하기도 어렵다.

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

이름 길이는 범위 크기에 비례해야 한다. 변수나 상수를 여러 곳에서 사용한다면 검색하기 쉬운 이름이 바람직하다.

int realDaysPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for (int j=0; j < NUMBER_OF_TASKS; j++) {
	int realTaskDays = taskEstimate[j] * realDaysIdealDay;
	int realTaskWeeks = (realTaskDays / WORK_DAYS_PER_WEEK);
	sum += realTaskWeeks;
}

만약 WORK_DAYS_PER_WEEK 대신 그냥 5를 사용한다면 검색하기 얼마나 힘들지 생각해보자.

클래스 이름

클래스 이름과 객체 이름은 명사나 명사구가 적합하다. Customer, WikiPage, Account 등.

Processor, Manager 등과 같은 단어와 동사는 피한다.

메서드 이름

동사나 동사구가 적합하다. 접근자Accsessor, 변경자Mutator, 조건자Predicate는 Javabean 표준에 따라 값 앞에 get, set, is를 붙인다.

생성자를 오버로딩할 때는 정적 팩토리 메서드를 사용한다. 메서드는 인수를 설명하는 이름을 사용한다.

Complex fulcrumPoint = Complex.FromRealNumber(23.0);

Complex fulcrumPoint = new Complex(23.0);

위 코드에서 첫번째 코드가 두번째 코드보다 더 좋은 방식이다.

기발한 이름은 피하라

재미난 이름보다는 명료한 이름을 사용하고, 특정 문화에서만 사용하는 농담은 피하는 편이 좋다.

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

추상적인 개념 하나에 단어 하나를 선택하고 이를 고수한다.

최신 IDE는 문맥에 맞는 단서를 제공한다. 활용해라.

메서드 이름은 독자적이고 일관적이어야 한다. 그래야 주석을 뒤져보지 않고도 프로그래머가 올바른 메서드를 선택한다.

말장난 하지 마라

다른 개념에 같은 단어를 사용한다는 것은 말장난에 불과하다.

프로그래머는 코드를 최대한 이해하기 쉽게 짜야 한다. 대충 훑어봐도 이해할 코드를 작성하는 것이 목표이다. 의도를 밝힐 책임은 저자, 프로그래머에게 있다.

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

코드를 읽을 사람도 프로그래머이다. 전산 용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 된다.

프로그래머에게 익숙한 기술 개념은 아주 많다. 기술 개념에는 기술 이름이 가장 적합한 선택이다.

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

우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다. 문제 영역 개념과 관련이 깊은 코드라면 문제 영역에서 이름을 가져와야 한다.

의미 있는 맥락을 추가하라

아래의 코드는 통계 추측(guess statistics) 메시지에 사용된다. number, verb, pluralModifier 변수 세 개는 함수 전반에서 사용되고 있다. 세 변수가 사용되는 맥락을 분명히 하기 위해 함수를 작은 조각으로 쪼개어 GuessStatisticsMessage 클래스에 넣었다.

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%",
			 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 = Integere.toString(count);
		verb = "are";
		pluralModifier = "s";
	}
	
	private void thereIsOneLetter() {
		number = "1";
		verb = "is";
		pluralModifier = "";
	}
	
	private void thereAreNoLetters() {
		number = "no";
		verb = "are";
		pluralModifier = "s";
	}
}

불필요한 맥락을 없애라

일반적으로는 짧은 이름이 긴 이름보다 좋다. 단, 의미가 분명한 경우에 한해서다. 이름에 불필요한 맥락을 추가하지 않도록 주의한다.

profile
내가그린솜뭉치

0개의 댓글