[Clean code] chapter 2. 이름

4 minute read

Overview

프로그래밍을 하면서 모든 순간에 이름을 사용하게 된다. 그 이름을 잘 지어서 좋은 코드를 만드는 규칙 몇가지를 소개하겠습니다.

규칙

의도를 분명히 밝혀라

이름을 통해서 다른 사람들에게 이런 것들을 전달해야 한다. 변수(혹은 함수나 클래스)의 존재 이유는? 수행 기능은? 사용 방법은? 따로 주석을 사용한다면 의도가 분명한 이름을 만들지 못했다. (나는 가끔 주석이 필요하다고 생각은 한다. 이름으로 모든 것을 설명하기 힘든 경우가 반드시 존재한다고 생각한다.)

ind d; // 경과 시간 (단위: 날짜)가 아닌

int daysSinceModification;
int daysSinceCreattion;

이런 이름을 사용하게 되면 주석 없이 명확한 이름으로 다른 사람들에게 큰 도움이 될 것이다.

public List<int[]> getThem() {
    List<List[]> list1 = new ArrayList<int[]>();
    for(int[] x : theList) {
        if (x[0] == 4)
            list1.add(x);
    }
    return list1;
}

위에 코드를 봐서 정확하게 어떤 일을 하는지 알수가 없다. list1, theList가 어떤 친구인지. x[0] == 4가 어떤 의미를 하는지 알 수가 없다.

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

위와 같은 방식으로 해당 데이터가 정확하게 어떤 것을 의미하는지. 어떤 역할을 하고 있는지 명확하게 하는 순간 이 친구가 어떤 일을 하고 있는지 알 수 있게 된다.

그릇된 정보를 피하라

기본적으로 프로그래머들은 list와 같은 고유 명사적인 의미를 가진 단어들을 잘알고 있다. 해당 변수에 list가 들어가게 당연히 생각하고 있는 것이 있을텐데 만약 실제로 그렇지 않는다면 크게 혼란스러울 것이다. 그런 것처럼 관념적으로 사용하는 단어에 대해서 잘 사용해야 한다.

의미 있게 구분하라

단순한 기능, 단순한 코드라고 하더라도 코드 작성자의 의도를 들어내는 게 더 좋은 코드를 더 읽기 쉬운 코드를 만들어낸다.

void copyChar(char a1[], char a2[]);

void copyChar(char source[], char destination[]);

위에 두 개의 차이를 보면 아주 간단해보이지만 코드 작성자의 의도를 명확하게 조금 더 이해할 수 쉽게 된다.

불용어 사용에 대해서 잘 생각해야 한다. 불용어는 실제로 어떤 의미가 존재하지 않은 용어이다. 그러다보니 실제 쓸데없는 내용을 전달하는 경우라고 말할 수 있다. 불용어를 사용하지 말라는 것은 아니지만 명확하지 않을 경우 더욱 불필요하다. (명확하지 않다.) Data, Info, the~~~ 이런 것들은 명확하게 이 용어를 설명해주지 못한다. 한마디로 쓸모없는 것들이다. NameNameString이 무엇이 다른가. 잘 생각해보고 작성해보자.

우리가 이름을 명확하게 작성하지 못하는 경우 이런 경우가 발생할 수 있다.

getAccount();
getAccounts();
getAccountInfo();

과연 저 위에 있는 3개 중에 내가 필요한 것이 무엇인지 어떻게 알 수 있을까?

검색하기 쉬운 이름을 사용하라

단순히 상수를 사용하는 것보다 단순한 변수를 사용하는 것보다 의마기 있는 이름을 사용하는 것이 좋다. 그리고 검색에는 이름이 긴 것이 더 좋다. 예를 들어서 7이라는 값 의미가 주에 존재하는 일수라고 한다면 다른 사람은 더 이해하기 쉽고 빠르게 찾을 수 있을 것이다. 책에서 나오는 이야기로는 이름 길이는 범위 크기에 비례해야 한다. 라는 내용이 나온다. 변수나 상수를 여러 곳에서 사용한다면 검색하기 쉬운 이름으로 만드는 게 맞다고 본다.

클래스 이름

명사나 명사구를 사용하는 것이 적합하다. Customer, WikiPage, Account 등이 좋은 예이다. Manager, Provessor, Data, Info 등은 같은 단어는 별로다.

메소드 이름

메서드 이름은 동사나 동사구가 적합하다. postPayment, deletePage가 예이다.

생성자를 중복정의할 때는 정적 팩토리 메서드를 사용한다.

생성자 사용을 제한하려면 해당 생성자를 private 선언한다. -> why?

기발한 이름은 피하라. 발음하기 쉬운 이름을 사용하라.

단순히 자기들만 아는 단어나 자기 지역 사람들만 아는 숙어, 은어와 같은 단어를 사용하는 것은 다른 사람들이 말하기도 어렵고 의미를 파악하기 어렵다.

모두가 알 수 있는 단어를 사용해서 의미 파악을 쉽게 하다.

발음하기 쉬운 단어 또한 잘 알지 못하는 단어일 확률이 높다. 혹은 직접 만든 단어이거나.

한 개념에 한 단어를 사용하라

추상적인 개념 하나에 단어 하나를 선택해 이를 고수해라. getfetch, retrieve로 여러 영어 단어로 표현하는 것은 굉장히 이해하기 어렵고 다른 의미를 가지고 있다고 생각할 수 있다. 그러니 같은 개념이면 같은 단어를 사용하는 것이 좋다.

그런 예로 DeviceManagerProtocalController는 근본적으로 어떻게 다른것인가? 어째서 둘 다 controller, manager로 될 수가 없는 것인가? 둘 다 다른 일을 하는것인가? 일관성 있는 어휘는 코드를 사용할 프로그래머에게 굉장히 큰 도움이 된다.

말장난을 하지 마라

한 단어를 두 가지 목적으로 사용하면 안된다. 다른 개념에 같은 단어를 사용하는 것은 말장난에 불과하다.

어느정도 비슷해 보이는 상황에서 add를 하는 메소드를 만들었다고 가정하자. 하는 행동이 비슷하고 add로 만든다는 것은 실제 로직을 더 헤깔리게 할 수 있다. 값을 더하고 리턴하는 add를 만들었는데 어떤 경우에는 값을 더하지만 리턴하지 않는데 add를 사용하거나 하는 것은 좋지 않다. 차라리 그런 메소드에는 appendinsert와 같은 다른 이름을 붙여야 한다.

해법 영역에서 가져온 이름을 사용하라

코드를 읽는 사람들은 프로그래머다. 전산 용어, 수학, 패턴 이런 것들에 대해서 기본적으로 알고 있기 때문에 오히려 네이밍에 있어서 좋은 영향을 줄 수 있다.

문제 영역에서 가져온 이름을 사용하라

해당 영역에 대한 도메인 존재하지 않더라도 꾸준히 개발하는 과정에서 문제 영역에 용어를 알아가게 되고 그것을 통해서 이해가 되는 경우가 많은 것이다. 그러기에 문제 영역에 관련 깊은 영어를 사용해보자.

의미 있는 맥락을 추가하라

이름 하나만으로 의미가 있는 경우가 있다. 하지만 대부분 이름 하나로는 모든 의미를 알 수 없다. 그래서 함수, 클래스, 이름 공간에 넣어서 맥락을 부여한다.

예를 들면, street, city, state 이런 정보를 보게 되었을 때 어떤 맥락인지 알 수 있다. 하지만 단순히 state만 존재한다면 그 의미를 파악하기가 어렵다.

그런 의미에서 함수에서 맥락 조금, 이름에서 맥락 조금, 알고리즘에서 최종 맥락을 파악하기 보다는 큰 클래스를 만들어서 그것에 대한 이름들에 대해서 맥락을 확실히 부여하고 그 클래스 밑에 여러 메소드를 만들면서 맥락을 명확하게 부여하게 되면 어떤 의미인지 더욱 파악하기가 쉽게 된다.

불필요한 맥락을 없애라

버스 정류장이라는 어플리케이션을 만드는데 모든 클래스 이름에 BusStation이라는 이름을 붙일 것인가?

IDE에서 B만 검색하기만 해도 모든 클래스가 다 나오게 될 것이다.

이름은 긴 이름보다 짧은 이름이 좋다. 단 그 이름이 모든 내용을 포함하고 있을 때이다. 일므에 불필요한 맥락을 추가하지 않도록 주의하자.

마치며

이름을 만드는데 무엇보다 문화적인 배경이 같아야 한다는 게 존재한다. 그래서 매우 어렵다.

사람들은 단순히 이름을 바꾸는 것에 대해서 무서워한다. 왜냐하면 다른 개발자들이 싫어할 것이라고 생각한다. 하지만 오히려 좋은 이름으로 바꾸는 시도, 도전은 다른 사람들에게 환영받는 도전이다. 혹시 그 도전이 쉽지 않다고 하더라도 이런 도전을 멈추면 안된다.

마무리

첫장에 네이밍이라는 것이 나왔다. 솔직히 이름 짓기가 매우 어렵다. 하지만 요즘 다른 사람들에 코드를 읽으면서 참 이름이라는 게 중요하다고 느낀다. 차근차근 연습하면서 좋은 이름 짓기에 도전해봐야 겠다.

Leave a comment