- 소프트웨어에서 이름은 변수, 함수, 클래스, 패키지 등 모든 곳에서 쓰인다.
- 이름을 잘 지으면 여러모로 편한데, 이 장에서는 이름을 잘 짓는 간단한 규칙을 몇 가지 소개한다.
https://xetown.com/topics/17032
- 의도가 분명한 이름이 정말로 중요하다는 사실을 거듭 강조한다.
- 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.
public List<int[]> test() {
List<int[]> theList = new ArrayList<>();
List<int[]> list = new ArrayList<>();
for (int[] x : theList) {
if (x[0] == 4) {
list.add(x);
}
}
return list;
}
- theList, list는 어떤 변수인지?
- theList에서 0번째 값이 왜 중요한지?
- 값 4는 무슨 의미인지?
private static final int STATUS_VALUE = 0;
private static final int FLAGGED = 4;
public void test2() {
List<int[]> gameBoard = new ArrayList<>();
List<int[]> flaggedCells = new ArrayList<>();
for (int[] cell : gameBoard) {
if (isFlagged(cell[STATUS_VALUE])) {
flaggedCells.add(cell);
}
}
}
private boolean isFlagged(int cellValue) {
return cellValue == FLAGGED;
}
- 여러 계정을 그룹으로 묶을 때 실제 List가 아니라면 accountList라 명명하지 않는다.
- 계정을 담는 컨테이너가 실제 List가 아니라면 프로그래머에게 그릇된 정보를 제공하는 셈이다.
- 이때는 accountGroup, bunchOfAccounts, Accounts라 명명한다.
// x
Account[] accountList = new Account[10];
// o
Account[] accounts = new Account[10];
// System.arraycopy(), Arrays.copyOf()
public static void copyChars(char[] a1, char[] a2) {
for (int i = 0; i < a1.length; k++) {
a2[i] = a1[i];
}
}
- 위 함수의 매개변수를 a1, a2가 아닌 source, destination을 사용한다면 코드 읽기가 훨씬 더 쉬워진다.
public static void copyChars(char[] source, char[] destination) {
for (int i = 0; i < a1.length; k++) {
a2[i] = a1[i];
}
}
for (int i = 0; i < 34; i++) {
s += (t[i] * 4) / 5;
}
private static final int WORK_DAYS_PER_WEEK = 5;
int realDaysPerIdealDay = 4;
int sum = 0;
for (int i = 0; i < NUMBER_OF_TASK; i++) {
int realTaskDays = taskEstimate[i] * realDaysPerIdealDay;
int realTaskWeeks = realTaskDays / WORK_DAYS_PER_WEEK;
sum += realTaskWeeks;
}
- 위 코드에서 sum이 별로 유용하진 않으나 최소한 검색이 가능하다.
- 이름을 의미있게 지으면 함수가 길어지지만, 검색이 보다 쉽다.
- 클래스 이름은 명사나 명사구가 적합하다.
- Customer, WikiPage, Account, AddressParser
- 메서드 이름은 동사나 동사구가 적합하다.
- postPayment, deletePage, save
- getName, setName
- 생성자를 중복정의 할 때는 정적 팩토리 메서드 를 사용한다.
Comple fulcrumPoint = Complex.fromRealNumber(23.0);
// 위 코드가 아래 코드보다 좋다
Complex fulcrumPoint = new Complex(23.0);
// 맥락이 불분명한 변수
private void printGuessStatistics(char candidate, int count) {
String number;
String verb;
String pluralModifier;
if (count == 0) {
number = "0";
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
);
}
- 위 함수는 코드를 끝까지 읽어보고 나서야 number, verb, pluralModifier 변수가 '통계 추측' 메시지에 사용된다는 걸 알 수 있다.
- 불행히도 독자가 맥락을 유추해야만 한다.
// 맥락이 분명한 변수
public class GuessStatisticMessage {
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) {
noLetter();
} else if (count == 1) {
oneLetter();
} else {
manyLetters(count);
}
}
private void noLetter() {
number = "0";
verb = "are";
pluralModifier = "s";
}
private void oneLetter() {
number = "1";
verb = "is";
pluralModifier = "";
}
private void manyLetters(int count) {
number = Integer.toString(count);
verb = "are";
pluralModifier = "s";
}
}
- GuessStatisticMessage라는 클래스를 만든 후 세 개의 변수를 넣었다.
- 이로 인해 세 개의 변수는 통계(Statistic)와 관련된 변수임이 분명해진다.
- 문장이나 문단처럼 읽히는 코드 아니면 적어도 표나 자료구조처럼 읽히는 코드를 짜는 데만 집중해야 마땅하다.
- 여느 코드 개선 노력과 마찬가지로 이름 역시 나름대로 바꿨다가는 누군가 질책할지도 모른다.
- 그렇다고 코드를 개선하려는 노력을 중단해서는 안된다.
- 이 장에서 소개한 규칙을 적용해 코드 가독성이 높아지는지 살펴보라.
- 이름 개선을 통해 단기적인 효과는 물론 장기적인 이익도 보장한다.