dev-writeup-2024 / march

개발 1일 1글 스터디
2 stars 0 forks source link

[03-05] 클린 코드 - 2편 #9

Open neolgu opened 4 months ago

neolgu commented 4 months ago

클린 코드 - 2편

들어가며

2장은 우리가 늘 고민하고 고민하는 이름짓기이다.

필자는 어마어마한 영어 문맹이기 때문에 변수명 지을때마다 영어를 검색하곤한다.

물론 영어를 잘 아는것이 좋지만, "적절한" 이름을 사용하는 것은 코드를 보는 다른이(혹은 미래의 본인)에 있어 이해하기 쉽게 도와준다.

그럼 어떻게 변수명을 짓는 것이 좋은지 알아보도록 하자.

의도를 분명히 밝혀라

당연하게 변수에는 그 사용 의도를 밝히는 것이 중요하다는 것은 누구나 아는 사실이지만, 간과하기 쉬운 것도 사실이다.

int d

여기서 d 가 의미하는 것은 무엇일까, 정답은 만든 본인만 안다는 것이다. 즉, 이 변수가 뭘하는 건지 의미를 밝히는 이름을 써야한 다는 것이다.

int elaspedTimeInDays;
int daysSinceCreation;

이런식으로 이름을 지으면 무엇에 대한 int 값인지 확실히 알수 있다.

좀 더 큰 코드로 보도록하자.

public List<int []> getThem() {
    List<int []> list1 = new ArrayList<int []>();

    for (int [] x: theList)
        if (x[0] == 4)
            list1.add(x);
    return list1;
}

이 코드를 보면 의문 사항이 생긴다.

  1. theList에 뭐가 있는지?
  2. 리스트의 0 번째 값이 뭐길래 그러는지
  3. 4 라는 값이 뭘 의미하는지
  4. 반환된 list1은 뭐에 사용되는지

자 이걸 이제 바꿔 보도록하자. 이 코드는 지뢰찾기 게임이다.

즉, theList는 게임판, 각 칸은 배열로 표시되고 배열의 0번째 값은 상태를 나타난다고 하고, 4는 깃발이 꽂힌 상태라고 하자. 이 개념을 그대로 이름에 적용해보도록 하자.

public List<int []> getFlaggedCells() {
    List<int []> flaggedCells = new ArrayList<int []>();
    for (int[] cell : gameBoard)
        if (cell[STATUS_VALUE] == FLAGGED)
            flaggedCells.add(cell);
    return flaggedCells;
}

코드의 구조는 분명 동일한데 뭘 하고 있는지 명확히 표시할 수 있다.

의미있게 구분하라

의도가 다르면 이름도 달라야한다. 반대로도 성립한다. 이름이 다르면 의도도 달라야한다.

public static void copyChars(char a1[], char a2[]) {
    for (int i = 0; i < a1.length; i++) {
        a2[i] = a1[i];
    }
}

물론 이정도 코드는 스트링을 복사하는 코드로 바로 알 수 있지만, 이 코드 내용을 보지 않고 단순히 함수를 호출해서 쓰는 거면 a1 -> a2로 복사하는 건지 그 반대인지 알 수 없다.

함수 이름으로 a1, a2source, destination으로 지정했으면 이러한 혼동을 발생시킬 일은 없을 것이다.

또한, 불용어도 되도록 사용하지 말아야 한다.

불용어 자체는 중복이 될 가능성이 높다. 코딩에서 불용어란 NameString, numList 등 굳이 의미가 모호한 중복되는 표현을 자제하라는 것이다.

getActiveAccount();
getActiveAccounts();
getActiveAccountInfo();

내용을 알지 모르는 팀원은 이 셋중 뭐가 내가 원하는 함수인지 알수 없다. 명확한 의도를 보여주거나 팀에서 설정한 관례를 따라서 만드는 것이 좋을 것이다.

나만 아는 내용, 나만 기억하는 내용을 그대로 적지마라

필자는 코테를 할 때, count를 cnt, current를 cur 등으로 줄여쓰는 것을 좋아한다.

하지만, 누군가 내가 푼 코테 코드를 보았을 때 잘 모르는 사람도 있을 것이다. 이렇게 나만 아는, 기억하는 것은 남이 볼때는 뭔지 모르게 되는 경우가 많다.

따라서 명료한 것이 중요하다.

물론, 모든 프로그래머들이 관례적으로 사용하는 반복문의 i, j, k 등은 그대로 쓰는 것도 좋다. (의미를 모두가 알고 있으니)

한 개념에는 한 단어를 사용하자

이 개념에는 일관성을 고려한 개념이라는 것을 분명히 한다.

여러 클래스에 add 라는 매서드가 있다고 할 때, 모든 add 메서드가 동일하게 기존값을 더하거나, 이어준다는 통일된 일관성을 보여준다면 오히려 제대로 이름 붙인 것이다.

하지만 여기서 집합에 숫자를 추가하는 다른 개념의 추가라는 것이 생긴다면 이름을 add로 지을 수 있을까.

정답은 "아니다".

add는 일관성 있게 그동안 사용왔으므로, add 대신 append나 insert로 바꾸는 것이 적절할 것이다.

이름을 바꾸는 것을 두려워하지 말자

우리들은 팀 혹은 여러 사람들과 협업할 때 다른 사람이 만든 변수 이름을 바꾸는 것을 피하곤 한다.

그 사람이 반대하거나 싫어할까 라는 이유로 이름을 바꾸는 것을 망설인다.

하지만, 더 좋은 이름이 있다면 바꾸는 것이 지금도, 앞으로의 개발에도 더 좋은 효과를 가져올 것이다.

그리고 요즘엔 IDE차원에서 알아서 이름을 refactor 시켜주는 기능도 있으니 더 좋은 이름이 생각난다면 언제든 바꾸도록하자.

(물론 바꾼 이름은 다른 사람들에게도 알려야함은 분명하다.)

마치며

역시 이름 짓는게 제일 어렵다고 생각한다. 그 사람의 언어권, 문화가 다르기에 모두가 긍정할 만한 이름을 짓는 것은 매우 어려운 일임은 맞다.

하지만, 그렇다고 해서 그 노력을 게을리하면 안된다. 필자는 변수명 하나로 30분을 고민했던적도 있다.

다음편은 함수로 예정되어 있습니다.

mingnuj commented 4 months ago

VSCode 같은 IDE는 보통 F2가 rename 단축키이니 기억하고 유용하게 쓰도록 합시다

snaag commented 4 months ago

가끔 의미가 모호한 변수를보면 눈물이나요............