의도가 드러나는 이름은 코드 이해도를 높이고 변경이 쉬워진다.
변수, 함수, 클래스의 존재 이유, 수행 기능, 사용 방법 을 이름으로 답할 수 있어야 한다.
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;
표현하려는 개념에 이름만 붙여도 코드가 상당히 나아진다.
gameBoard
라는 2차원 배열을 반복하면서 각 셀을 확인한다.STATUS_VALUE
)가 깃발이 꽂힌 (FLAGGED
) 상태가 되면 해당 셀을 flaggedCells
리스트에 추가한다. public List<int[]> getFlaggedCells(){
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard)
if(cell[STATUS_VALUE]==FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
isFlagged()
라는 함수를 사용해 FLAGGED 라는 상수를 감출 수 있다. public List<**Cell**> getFlaggedCells(){
List<Cell> flaggedCells = new ArrayList<int[]>();
for (Cell cell : gameBoard)
if(cell.**isFlagged()**)
flaggedCells.add(cell);
return flaggedCells;
}
같은 이름에 연속적인 숫자만 덧붙이거나 (a1, a2, a3,…) 불용어를 추가하지 말자.
(불용어란 문장 내에서 빈번하게 발생하여 의미를 부여하기 어려운 단어들을 의미한다. 예를 들어 a, an, the 등이 있다.)
클래스 이름을 ProductInfo 혹은 ProductData 라고 한다면 개념을 구분하지 않고 이름만 다르게 지은 것이다.
moneyAmount 와 money / customerInfo 와 customer / accountData 와 account 등의 이름은 서로 구분이 안된다.
지적인 대화가 가능해진다.
private Date genymdhms; 보다는 private Date generationTimestamp; 를 사용하자!
이름을 의미 있게 지으면 함수가 길어지지만 찾기가 쉬워진다.
for(int j=0; j<34; j++){
s += (t[j]*4)/5;
}
int realDaysPerIdealDay = 4;
int WORK_DAYS_PER_WEEK = 5;
유형이나 범위까지 인코딩에 넣으면 그만큼 이름을 해독하기 어렵다.
예전에는 멤버 변수에 m_ 이라는 접두어를 붙였지만, 이제는 그럴 필요가 없다.
하지만 때로는 인코딩이 필요하다.
루프 범위가 아주 작고 다른 이름과 충돌하지 않는다면 반복 횟수를 세는 i, j, k 는 사용해도 괜찮다. (l 은 절대 안된다!)
클래스 이름 (객체 이름)
명사나 명사구가 적합하다. 동사는 사용하지 않는다.
좋은 예 : Customer, WikiPage, Account, AddressParser
나쁜 예 : Manager, Processor, Data, Infor
메서드 이름
동사나 동사구가 적합하다.
좋은 예 : postPayment, deletePage, save
접근자(Accessor), 변경자(Mutator), 조건자(Predicate)는 javabean 표준에 따라 값 앞에 get, set, is를 붙인다.
String name = student.getName();
customer.setName("amy");
if(payment.isChecked())...
생성자를 중복 정의(overload)할 때는 정적 팩토리 메서드를 사용한다. 메서드는 인수를 설명하는 이름을 사용한다.
Complex fulcrumPoint = Complex.FromRealNumber(23.0);
// 아래 코드가 더 좋다.
Complex fulcrumPoint = new Complex(23.0);
// 생성자 사용을 제한하려면 생성자를 private로 선언한다.
너무 독창적인 이름보다는 의도가 명료한 이름을 지어야 한다.
똑같은 메서드를 클래스마다 다르게 부르면 혼란스럽다. 메서드 이름은 독자적이고 일관성이 있어야 한다.
한 단어를 두 가지 목적으로 사용하면 안된다. ‘일관성’을 고려해 add 라는 단어를 선택하고 모든 add 메서드가 기존 값을 더하여 새로운 값을 만든다고 가정한다면, 집합에 값 하나를 추가하는 새로운 메서드를 add 라고 불러서는 안된다. insert 나 append 라는 이름이 적당하다.
전산 용어, 알고리즘 이름, 패턴, 수학 용어 등을 사용해도 된다.
문제 영역 개념과 관련이 깊은 코드라면 문제 영역에서 이름을 가져와야 한다. 코드를 읽는 프로그래머가 해당 분야 전문가에게 의미를 물어 파악할 수 있다.
마지막 수단으로 접두어를 붙인다.
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) {
thereAreNoLetters();
} else if (count == 1) {
thereIsOneLetter();
} else {
thereAreManyLetters(count);
}
}
private void thereAreManyLetters(int count) {
number = Integer.toString(count);
verb = "are";
pluralModifier = "s";
}
private void thereIsOneLetter() {
number = "1";
verb = "is";
pluralModifier = "";
}
private void thereAreNoLetters() {
number = "no";
verb = "are";
pluralModifier = "s";
}
}
Gas Station Deluxe 라는 애플리케이션을 만든다고 해서 모든 클래스 이름을 GSD로 시작하는 것은 안된다.
의미가 불분명하고 불필요한 맥락의 GSD 는 제외하자!
accountAddress 와 customerAddress 는 Address 클래스의 인스턴스로는 좋은 이름이지만, 클래스 이름으로는 적합하지 않다.
코드를 처음 읽는 사람도 이해하기 쉽도록 명명한다.