프리코스 공통 피드백 중 변수 이름에 자료형을 사용하지 말라는 피드백이 있었다.
1
2
List<Car> carList = cars.getCars(); // X
String carNameStr = car.getName(); // X
왜 변수명에 자료형을 사용하면 안될까?
1
List<Car> carList = cars.getCars();
위 코드를 보자. 문제가 없어보인다.
하지만 만약 car를 담는 컬렉션을 가지고 있는 cars가 자료형이 List가 아닌 Set과 같은 자료형으로 바뀐다면?
carList라는 변수명은 car들을 담고 있는 Set의 의미에는 어울리지 않는다. 변수명까지 carSet으로 바꾸어야하고, carList를 사용하고 있던 부분까지 전부 수정해야 하는 문제가 생기는 것이다.
변수명은 남에게 의도를 드러내는 것이 중요하다. 자료형을 붙이지 않는 변수 이름만 잘 지어도 자료형 같은 경우는 타입을 통해 어떤 의도인 지 드러낼 수 있다.
좋은 변수 명을 짓는 방법
의도를 분명이 밝혀 이름을 짓자
- 따로 주석이 필요하다면 의도를 분명하게 드러내지 못했다는 뜻이다.
- 변수 이름은 변수가 표현하고 있는 것을 완벽하게 설명해야 한다.
- 이름은 구체적으로 지어야 한다. 모호하거나 하나 이상의 목적으로 사용될 수 있는 일반적인 이름은 보통 좋지 않은 이름이다.
1
Set<BoardSquare> findSquaresToRemove(BoardSquare s) {}
BoardSquare의 s는 이름만 보았을 때 String의 s인지, Square의 s인지 한 번에 파악할 수 없다.
1
Set<BoardSquare> findSquaresToRemove(BoardSquare boardSquare) {}
boardSquare과 같이 변경하여 이름을 통해 의도를 분명하게 드러내야 한다.
협업을 염두해서 짓자
1
2
3
4
5
private void validateNumericPosition(String numbers) {
for (int i = 0; i < numbers.length(); i += 2) {
/...
}
}
위 코드의 for문에서 i += 2가 의미하는 부분이 무엇인지 정확히 드러나지 않는다. 다른 사람이 목적을 파악하기 위해서는 코드를 분석해야 하는 것이다.
1
2
3
4
5
private void validateNumericPosition(String numbers) {
for (int i = 0; i < numbers.length(); i += numberIndex) {
/...
}
}
2 라는 숫자에 의미있는 네이밍을 부여하면 숫자만 걸러내기 위한 의도임을 알 수 있다.
맥락을 고려해서 짓자.
- 이름이 지나치게 짧을 경우 변수의 용도를 알기 어렵다.
- 의도가 불분명한 짧은 이름보다는 의미있는 긴 이름이 낫다.
- 하지만 쓸데없이 구구절절한 이름은 오히려 독이 된다.
1
2
3
4
public class User {
String userName;
int userAge;
}
위 변수들은 User라는 클래스 내부에 존재함으로써 이미 user에 대한 정보를 의미하는 것을 알 수 있다. 따라서 굳이 name과 age앞에 user를 다시 한 번 붙일 필요가 없는 것이다.
1
2
3
4
public class User {
String name;
int age;
}
위와 같이 user를 붙이지 않아도 충분히 의도를 드러낼 수 있다.
불린 변수의 네이밍에 대해
- 전형적인 불린 변수의 이름을 사용한다.
- done, error, found, success, ok 등
- 만약 성공했다는 것을 정확하게 설명하는 구체적인 이름이 있다면 그 이름으로 대체하는 것이 좋다.
- found, processingComplete 등
- 참이나 거짓을 의미를 함축하는 불린 변수의 이름을 사용한다.
- status, sourceFile 같은 변수들은 좋지 못한 이름이다.
- statusOK, sourceFileAvailable 등과 같이 의미가 있는 이름이 좋다.
- 긍정의 불린 변수 이름을 사용한다.
1
2
if (notFound == false) { /... }
if (found == true) { /... }
둘은 같은 의미이다. 하지만 아래가 훨씬 읽기 편하다. 부정이 되었을 때 한 번에 의미를 파악하기 어렵다.
- 접두어 is
자바에서는 접두어 is를 붙여 불린 메소드나 변수 명을 짓는다. 하지만 반드시 그런 것은 아니고 상황에 따라 선택하여 변수 명을 지으면 된다.
메서드가 여러번 호출된 한눈에 보기 힘든 코드
1
2
3
4
5
6
7
8
9
private static final String FORMAT_SYMBOL = "//(.*)\\\\n(.*)";
public static List<String> customSplit(String input) {
Matcher matcher = Pattern.compile(FORMAT_SYMBOL).matcher(input);
if (matcher.find()) {
return Arrays.asList(matcher.group(2).split(Pattern.quote(matcher.group(1))));
}
/...
}
위 코드의 return 부분은 한 줄에 많은 기능이 있어 코드를 읽기 어렵다.
1
2
3
4
5
6
7
8
9
10
11
12
private static final String FORMAT_SYMBOL = "//(.*)\\\\n(.*)";
public static List<String> customSplit(String input) {
Matcher matcher = Pattern.compile(FORMAT_SYMBOL).matcher(input);
if (matcher.find()) {
String splitSymbol = matcher.group(1);
String content = matcher.group(2);
return Arrays.asList(content.split(Pattern.quote(splitSymbol)));
}
/...
}
일부를 변수로 선언하여 가독성을 훨씬 높여줄 수 있다.