이번 포스팅에선 클린 코드 2장 - 의미 있는 이름을 정리해보겠습니다.
매 장마다 정말 중요한 내용들이네요.
의미 있는 이름?
클래스, 인터페이스, 변수, 인자 등 다양한 곳에 개발자가 직접 이름을 붙혀가면서 개발을 하고 있습니다.
수 많은 이름을 붙혀줘야 하는데 고민하기 싫다고 그냥 의미 없는 이름을 붙혀준다면? 바로 나쁜 코드가 발생합니다.
그럼 어떻게 의미 있는 이름을 붙혀야 하는지 하나씩 알아보겠습니다.
의미 있는 이름을 짓는 법
1. 의도를 분명히 밝혀라
의도를 분명히 하는 변수명을 짓는데 고민하는 시간이 아까워도 투자해야 합니다.
그 이름을 짓으므로 절약하는 시간이 더 많기 때문입니다.
예1)
int d; // 경과 시간(단위: 날짜)
위처럼 경과 시간을 그냥 d라고 단순하게 줘버리면 무슨 의도인지 알 수가 없습니다.
int elapsedTimeInDays;
int daysSinceModification;
int daySinceCreation;
int fileAgeInDays;
위처럼 경과 시간의 뜻이 잘 담긴 변수명을 사용하니 의도가 분명해졌습니다.
예2)
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
무슨 의도로 작성된 코드인지 아시겠나요?
1) theList는 어떤 리스트인지?
2) x[0] == 4는 무슨 의미인지?
의도가 분명하지 않은 변수 덕분에 어떤 코드인지 알 수가 없네요.
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells
}
위와 같이 의도가 담긴 변수명으로 변경하니 정확히는 모르겠지만 어느정도 무슨 로직인지 알 수 있겠네요.
2. 그릇된 정보를 피하라
예1) 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용하지 말자
int hp = 3;
음.. hp? 게임에서 사용하는 health point인가? 아니면 컴퓨터 제조사 hp인가?
아닙니다. hypotenuse 직각삼각형의 빗변을 약어로 쓴 겁니다.
널리 쓰이고 있는 단어를 피해서 사용하자!
예2) List를 잘 붙히자
String[] alphabetList = {"a", "b", "c"};
변수명에 List를 넣으려면 진짜 타입이 List인 경우에만 넣는게 좋습니다.
Collection인 경우 alphabets 처럼 s를 붙혀서 복수로 붙혀주는 게 좋습니다.
나중에도 나오겠지만 변수명에 타입 이름을 넣는 건 안 좋습니다.
예3) 비슷해보이는 문자를 쓰지말자
int a = l;
if (O == l)
a = O1;
else
l = 01;
소문자 l 과 숫자 1, 대문자 O와 숫자 0 과 같이 헷갈리는 문자는 쓰지 말아야 합니다.
실제 저렇게 짜는 사람이 과연 있을까 싶지만... ㅎㅎ...
3. 의미 있게 구분하라
읽는 사람이 차이를 알도록 이름을 지어라.
예)
productInfo vs productData
getActiveAccount() vs getActiveAccountInfo()
moneyAmount vs money
customerInfo vs customer
위와 같은 변수가 있으면 어떤 차이가 있는지 알 수가 없습니다. 의미 있게 구분해야 합니다.
4. 인코딩을 피하라
- 헝가리식 표현법
예) phoneString, nameString, moneyLong
변수명에 타입이 들어가면 타입이 변경되어도 이름이 바뀌지 않기 때문에 착오를 일으킬 수 있습니다.
- 인터페이스 클래스와 구현 클래스
ShapeFactory (interface)
IShapeFactory보다 ShapeFactoryImpl or CShapeFactory가 더 좋습니다.
5. 클래스 이름
클래스 이름은 명사나 명사구가 적합한다.
예) Customer, WikiPage, Account
6. 메서드 이름
메서드 이름은 동사나 동사구가 적합하다.
예) getName, doGet, calculate
7. 한 개념에 한 단어를 사용하라
예) getStudent, fetchStudent, retrieveStudent
위 3개는 Student를 가지고 오는 메서드인데 어떤 건 get, 어떤 건 fetch, 어떤 건 retrieve 입니다.
위 3개 어떤 거든 통일해서 쓰는 게 제일 읽기 편합니다.
8. 말장난을 하지 마라
예) "한 개념에 한 단어를 사용하라" 라는 규칙을 따라
두 개를 더하거나 이어서 새로운 값을 만드는 메소드를 add라고 칭했다.
근데 개념이 좀 다른 리스트에 값을 하나 추가하는 메소드에 add라고 붙힌다면?
이건 말장난입니다. insert나 append가 어울립니다.
9. 해법 영역에서 가져온 이름을 사용하라
개발자들끼리 주로 사용하는 디자인 패턴에서 나오는 단어를 사용하는 것이 좋다.
코드를 읽고 고치는 사람도 개발자이기 때문이다.
예) AccountVisitor, JobQueue
10. 도메인 영역에서 가져온 이름을 사용하라
해법 영역에서 쓸 단어가 없다면 도메인 영역에서 사용 하는 단어를 사용하는 것이 좋다.
예) seller, buyer
11. 의미 있는 맥락을 추가하라
예)
public class AddressMaker {
private String name;
private String zipCd;
private String addr1;
private String addr2;
public String[] getAddress() {
return new String[]{name, zipCd, addr1, addr2};
}
}
name, zipCd, addr1, addr2는 하나의 주소를 만들 때 반드시 사용되기 때문에 아래 처럼 Address 클래스로 묶어서 사용하는 것이 좋다.
public class AddressMaker {
private Address address;
public Address getAddress() {
return address;
}
}
12. 불필요한 맥락을 없애라
예) GS25라는 모듈에 고객과 매니저를 추가한다고 아래와 같이 GS25Customer, GS25Manager로 짓는다면 어떤가요?
GS25Customer, GS25Manager -> Customer, Manager로 쓰는 게 훨씬 더 적절합니다.
불필요한 맥락은 제거하는 게 읽기 쉽습니다.
코드 2장 의미 있는 이름 정리가 끝났습니다.
좋은 이름을 짜려면 문화적인 배경, 도메인 지식, 개발 지식 등 여러 지식이 필요하기 때문에 열심히 공부하고 익혀야겠습니다.
'Clean Code' 카테고리의 다른 글
[클린 코드] 6장 - 객체와 자료 구조 (Objects and Data Structures) (0) | 2022.03.06 |
---|---|
[클린 코드] 5장 - 형식 맞추기 (Formatting) (0) | 2022.03.01 |
[클린 코드] 4장 - 주석 (Comments) (0) | 2022.03.01 |
[클린 코드] 3장 - 함수 (Functions) (0) | 2022.02.28 |
[클린 코드] 1장 - 깨끗한 코드 (Clean Code) (0) | 2022.02.27 |
댓글