- 변수나 클래스에 따로 주석 설명이 필요하다면, 의도를 분명히 드러내지 못했다는 것이다.
- 코드의 함축성 이 문제 → 독자가 다 알고 있을것이라 생각하지 말고, 정보를 제공해야한다.
// ASIS
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList)
if(x[0] == 4)
list1.add(x);
return list1;
}
// TOBE
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell : gameBoard)
if(cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
- 나름대로 널리쓰이는 의미 일지라도, 다른의미와 혼동될 수 있다.
: hp = (1) 유닉스 플렛폼 이나 변종을 의미. (2) 빗변(hypotenuse) 를 의미- 실제 리스트가 아니라면 xxxList 라 명명을 피하라.
: accountList → accountGroup, bunchOfAccounts, Accounts- 유사한 이름을 피하라.
: XYZControllerForEfficientHandlingOfStrings & XYZControllerForEfficientStorageOfStrings- 유사한 개념은 유사 표기법을 사용 → 이름만으로 객체를 선택할 수 있게 하라.
최악의 코드 : 숫자 0, 1 영문 O, l 로 정보에 혼동 발생
int a = l;
it (O == l)
a = Ol;
else
l = 01;
- 연속적인 숫자 명명을 피하라. (a1, a2 ... aN)
public static void copyChars(char a1[], char a2[]) {
for (int i = 0; i < a1.length; i++) {
a2[i] = a1[i]
}
}
// source 와 destination으로 인수를 변경한다면 더 읽기 쉬워진다.
- 불용어(noise word)를 추가하는 방식은 적절하지 못하다. 이름이 다르다면, 의미도 달라야한다.
- 읽는 사람이 차이를 알도록 이름을 지어야 한다.
- a, the, Info, Data : 의미가 불분명한 불용어
- ProductInfo 또는 ProductData → Product
- NameString → Name보다 나은것이 없다. (Name이 부동소수가 될리가 없다.)
- CustomerObject & Customer 불용어는 중복을 일으킨다
- getAccount(); VS getAccounts(); VS getAccountInfo(); → 차이를 설명할 수 있는가?
- 변수이름에 사용금지 단어 : variable, table
프로그래밍은 사회활동이다.
ex. genymdhms(generate data, year, month, day, hour, minitue, second)
pronouce. 젠 와이 엠 디 에이취 엠 에스 or 젠 야 무다 힘즈
// ASIS
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
// TOBE
private Date generationTimeStamp;
private Date modificationTimeStamp;
private final String recordId = "102";
- 문자 하나를 사용하는 이름과 상수 는 검색이 힘들다.
: 만약 변수명이 e라면, 거의 모든 파일에서 검색될 것 이다.- 이름의 길이는 범위 크기에 비례해야 한다.
// ASIS
for(int j=0; j>34; j++){
s += (t[j]*4)/5;
}
// TOBE
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] * realDaysPerIdealDay;
int realTaskWeeks = (realTaskDays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
// -> sum으로 변경하면서 검색에 용이한 변수가 되었다.
- 유형이나 범위 정보까지 인코딩에 넣으면, 그만큼 이름을 해독하기 어려워 진다.
- 문제해결에 집중하는 개발자에세 인코딩은 불필요한 정신적 부담이다.
📁 헝가리식 표기법
이름 길이가 제한되고, 컴파일러가 타입 점검을 하지 않던 과거에 사용하던 방식.
이는 타입변경시 이름을 변경하지 않아, 독자를 헷갈리게 한다.
📁 멤버 변수 접두어
과거 멤버변수에 m_이라는 접두어를 사용했다.
📁 인터페이스 클래스와 구현 클래스
인코딩이 필요한 경우도 있다.
ShapeFactory.class
ShapeFactoryImpl.class
독자가 변수명을 변환해야 한다고 생각한다면, 변수명은 바람직하지 않은것이다.
- 문자하나만 사용하는 변수는 문제가 있다. 루프에서 i,j,k는 허용 (단, l은 안된다!)
- 전문 프로그래머는 명료함이 최고라고 생각. 자신의 능력을 통해 남들이 이해하는 코드를 작성한다.
- 명사, 명사구
- Manager, Processor, Data, Info 와 같은 단어를 피하고, 동사는 사용하지 않는다.
- 동사, 동사구
- 자바진 표준 : 앞에 접두어를 붙인다.
- 접근자(Accessor) : get
- 변경자(Mutator) : set
- 조건자(predicate) : is
- 생성자 Overload : 정적 팩토리 메서드를 사용
// ASIS
Complex fulcrumPoint = new Complex(23.0); (X)
// TOBE
Complex fulcrumPoint = Complex.FromRealNumber(23.0); (O)
// 인수를 설명하는 메서드 명을 사용
구어체나 속어, 특정 문화에서만 사용되는 변수를 피하라.
메서드 이름은 독자적이고 일관적이어야 한다. → 일관성 있는 코드는 사용할 프로그래머에게 선물이다.
- controller, manager, driver
한 단어를 두가지 목적으로 사용하지 마라.
- add : 메서드의 매개변수와 반환값이 다름에도 같은 메서드명을 사용.
- 맥락이 다르다면, 다른 메서드 명을 사용.
- 코드를 읽을 사람도 프로그래머다.
- 전산용어, 알고리즘, 패턴, 수학 용어등을 사용해도 괜찮다.
: AccountVisitor(VISITORV패턴), JobQueue
- 도메인기반의 명명. 분야 전문가에게 의미를 물어 파악할 수 있다.
- "해법영역"과 "문제영역(도메인)"을 잘 구분 하여 사용하는 것이 우수한 프로그래머이다.
변수의 맥락이 불분명 하다면, 클래스 묶어서 관리 하는 것을 통해 맥락을 분명하게 한다. (36p)
의미가 분명한 경우에, 일반적으로 짧은 이름이 긴 이름 보다 좋다.
- 의미없는 접두어는 생략한다. ex. GSD 회계 모듈 관련 클래스라 해서 GSDAccountAddress 는 적합하지 않다.
- Adress (클래스 이름) → accountAddress, customerAddress (인스턴스 이름)