개발놀이터
리팩토링 (1) : 의미있는 이름 본문
우리는 이름을 정말 많이 짓습니다. 클래스, 변수, 인터페이스, 추상 클래스, JAR파일, WAR파일 모두 이름을 붙이게 됩니다.
그러므로 이름을 잘 붙이는 것은 의미있습니다. 그리고 잘 못지은 이름은 가독성을 떨어뜨리기 마련이죠.
이번 포스팅에선 의미있게 이름을 붙이는 방법에 대해서 설명해보도록 하겠습니다.
의미있는 이름
의도를 분명히 밝혀라
우리는 가끔 변수명을 이렇게 짓곤 합니다.
int d;
하지만 개발할 때 당시만 기억나고 한참 뒤에 이 변수를 보면 무슨 변수인지 헷갈릴 때가 많습니다.
그러므로 우리는 아래와 같이 바꿔야합니다.
int daysSinceModification;
이에 조금 연장선상의 코드들을 한번 보시죠.
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<>();
for (int[] x : theList) {
if (x[0] == 4) {
list1.add(x);
}
}
return list1;
}
이 코드의 문제점은 다음과 같습니다.
- getThem이 뭘 가리키는지 모른다.
- theList에 무엇이 들어있는지 모른다.
- 값 4는 무슨 의미인지 모른다.
- 함수가 반환하는 list1을 어떻게 사용해야 하는지 모른다.
때문에 우리는 변수를 설정하고 그 변수에 의도를 설명해줄 필요가 있습니다.
위의 상황은 바로 지뢰찾기 게임의 한 부분이었습니다. 그럼 이제 명확히 theList가 게임보드라는 것을 알 수 있겠죠. 배열의 0번째에는 칸의 상태가 들어있고, 4라는 숫자의 뜻은 깃발이 꽂힌 상태를 말합니다.
그럼 아래와같이 코드를 리팩토링할 수 있습니다.
private static int STATUS_VALUE = 0;
private static int FLAGGED = 4;
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<>();
for (int[] x : gameBoard) {
if (x[STATUS_VALUE] == FLAGGED) {
flaggedCells.add(x);
}
}
return flaggedCells;
}
이렇게 고치면 다른 개발자가 봤을 때 어떤 의도를 가지고 코딩했는지 알 수 있겠죠?
의미있게 구분하라
보통 우리가 아무생각 없이 붙이는 변수명에 큰 의미가 없는 경우가 많습니다.
moneyAccount 와 int money 는 구분이 안된다.
customerInfo 와 customer 역시 구분 안된다.
accountData 와 account, theMessage 와 message 구분 X
의미없는 미사여구는 변수명만 길어지게 할 뿐 의미가 분명해지진 않습니다. 안티패턴이라 절대 하지말라는 말은 아니지만 명확한 변수명은 아니라는 것이죠.
줄임말을 쓰지 말아라
private Date genymdhms;
private Date modydhms;
여러분 이게 무슨 변수인지 알겠나요? 아마 설명을 듣기 전에는 절대 모를것임에 확신합니다.
private Date generationTimestamp;
private Date modificastionTimestamp;
아마 이렇게 바꾸는게 조금 더 명확할 것입니다.
검색하기 쉬운 이름을 사용하라
for (int j = 0 ; j < 34 ; j++) {
s += (t[j] * 4) / 5;
}
이 역시 앞에서 설명드렸던 의도를 분명히 하라에 어긋납니다. 위에서 말한 내용과 일맥상통하는 말이긴 합니다만 의도가 조금 다른데요.
만약 이 메서드의 for문을 검색할 때 j를 찾는다거나 s를 찾으면 얼마나 많은 j와 s가 등장할까요? 우리는 이런 것을 피하기위해 의도를 나타내면서 검색하기 쉬운 이름을 사용해야합니다.
private static final int WORK_DAYS_PER_WEEK = 5;
private static final int NUMBER_OF_TASKS = 34;
public static void main(String[] args) {
int realDaysPerIdealDay = 4;
for (int j = 0; j < NUMBER_OF_TASKS; j++) {
int realTaskDays = taskEstimate[j] * realDaysPerIdealDay;
int realTaskWeeks = (realTaskDays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
}
//생략된 변수가 있을 수 있습니다.
그릇된 정보를 피하라
만약 한 모듈에서 XYZControllerForEfficientHandlingOfStrings 라는 꽤 긴 이름을 사용하고 있다고 가정해봅시다. 그리고 조금 떨어진 모듈에서 XYZControllerForEfficientStorageOfStrings 라는 이름을 사용하고 있다고 하면 이 둘이 구분이 되시나요?
이 둘은 너무 비슷해서 의미가 흐려집니다. 이런 이름들은 피해야겠습니다.
의미있는 맥락을 추가하라
만약 어떤 모듈에서 아래와 같은 변수를 사용하고 있다고 가정해봅시다.
String firstName;
String lastName;
String street;
String houseNumber;
String city;
String state;
String zipcode;
일련의 변수들을 보고있으니 바로 주소라는 것을 알 수 있겠습니다.
하지만 만약 어떤 메서드에서 state 하나만 사용하고 있다면 어떨까요? 이 state 가 주소의 일부분이라는 것을 알 수 있을까요?
때문에 우리는 이런 상황에서 의미있는 맥락을 추가해주는 것이 좋습니다.
String addrFirstName;
String addrLastName;
String addrStreet;
String addrHouseNumber;
String addrCity;
String addrState;
String addrZipcode;
마치며
여기까지 의미있는 이름 부분이 끝났습니다. 아무래도 이름을 짓는 부분은 크게 어려운 것 없이 잘 지나간 것 같습니다. 조금 더 신경써야 할 부분들이 몇개 보이긴 하네요.
모든 파트를 포스팅하고 제 프로젝트에 이 부분들을 녹여가면서 깨끗해질 제 코드들을 기대해보며 마무리짓도록 하겠습니다.
긴 글 읽어주셔서 감사합니다. 오늘도 즐거운 하루 되세요~
'리팩토링' 카테고리의 다른 글
JWT 필터 리팩토링 (0) | 2023.07.23 |
---|---|
리팩토링 (2-1) : switch 문 인터페이스, 추상클래스로 리팩토링 (0) | 2023.07.23 |
리팩토링 (2) : 함수 (0) | 2023.07.22 |
리팩토링 (0) : 개요 (0) | 2023.07.22 |