오봉이와 함께하는 개발 블로그

CleanCode - 의미있는 이름 본문

이론

CleanCode - 의미있는 이름

오봉봉이 2023. 12. 26. 22:32
728x90

의미있는 이름

Robert C. Martin - Clean Code의 의미있는 이름 에 관한 내용을 보고 생각하는 내용을 적는다.
책을 보면서 적기 때문에 책을 같이 보고 있지 않다면 다소 불친절한 글이 될 수 있을 거 같다.

의도를 분명히 밝혀라

public class Member {
    int a;
}

int a 가 뭔지 알 수 있는 사람이 있을까? 코드 작성자도 한 달이 지난 후 보면 저 a를 사용하는 곳을 모두 찾아야 어떤 값인지 알 것이다.
변수명에서 어떠한 힌트도 얻을 수 없다.
혹시 저렇게 변수를 만들고 있는 사람이 이 글을 본다면 아래와 같이 명확한 이름을 사용하는 것이 어떤기?

public class Member {
    int age;
}

조금 더 복잡한 예제를 보자.

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

코드의 동작은 보이지만 어떤 기능인지 전혀 보이지 않는다. 어떤 도메인에서 구현되는 코드인지 알아도 알 수 없을 것이기 때문에 도메인을 몰라서 발생하는 문제도 아니다.

  1. theList가 무엇인가
  2. theList의 0번째 인덱스는 왜 중요한가
  3. 값 4는 어떤 의미길래 조건문에서 사용하는가
  4. 반환되는 list1의 의미는 뭔가, 어떻게 사용하는가

책에서는 지뢰찾기 게임을 만든다 가정하고 아래와 같은 코드를 제시한다.
이제 여기부턴 지뢰찾기의 규칙을 아는지 모르는지에 따라 어떤 기능을 하는지 알 수 있을 거 같다. (지뢰찾기 규칙을 몰라서 나는 모른다.)

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 List<Cell> getFlaggedCells() {
    List<Cell> flaggedCells = new ArrayList<int[]>();
    for (Cell cell : gameBoard)
         if (cell.isFlagged)
             flaggedCells.add(cell);
    return flaggedCells;
}
  1. 정수형 배열을 클래스로 감싸 더 명확하게 했다.
  2. 조건문의 조건을 함수로 추출하여 getFlaggedCells만 봤을 때 조건을 더 명확하게 하였다.

그릇된 정보를 피하라

책에서는 아래와 같이 설명한다.

hp, aix, sco는 변수 이름으로 적합하지 않다. 유닉스 플랫폼이나 유닉스 변종을 가리키는 이름이기 때문이다. 직각삼각형의 빗변 hypotenuse을 구현할 때는 hp가 훌륭한 약어로 보일지라도 hp라는 변수는 독자에게 그릇 된 정보를 제공한다.

여러 계정을 그룹으로 묶을 때, 실제 List가 아니라면, accountList라 명명하지 않는다. 프로그래머에게 List라는 단어는 특수한 의미다. 계정을 담는 컨테이너가 실제 List가 아니라면 프로그래머에게 그릇된 정보를 제공하는 셈이다. 그러므로 accountGroup, bunchOfAccounts, 아니면 단순히 Accounts라 명명한다.

서로 흡사한 이름을 사용하지 않도록 주의한다. 한 모듈에서 XYZControllerForEfficientHandlingOfStrings라는 이름을 사용하고, 조금 떨어진 모듈에서 XYZControllerForEfficientStorageOfStrings라는 이름을 사용한다면?

내가 이해하기로는 이상한 약어 혹은, 예약어, 흡사한 이름을 사용하지 말라는 것으로 보인다.

의미있게 구분하라

public static void copyChars(char a1[], char a2[]) {
    .........
}

위와 같은 코드가 있을 때 a1을 source로 a2를 destination으로 사용한다면 코드 읽기가 훨씬 더 쉬워진다.

public Product{
    ....
}

public ProductInfo{
    ....
}

Product에 ProductInfo는 서로 다른 역할을 하는 클래스더라도 어떤 의미인지 명확하게 전달되지 않는다.

int amout;
int moneyAmount;

amout와 moneyAmount는 어떤 차이인지 알겠는가? 나도 생각없이 예시를 만들어서 모르겠지만 생각하고 짜도 얼마 지나지 않아 금방 까먹을 것이다.

이번 내용은 첫 번째 의도를 분명히 밝혀라 와 어느정도 통하는 내용이다

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

이번 내용을 한 문장으로 요약하라고 하면 상수를 사용해라 라고 요약할 수 있겠다.

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

if (x[STATUS_VALUE] == FLAGGED)if (x[0] == FLAGGED)
0이 어떤 값을 하는지 STATUS_VALUE로 하는 것이 더 명확한 전달이 될 것이고, STATUS_VALUE보단 더 특별하게 변수를 만드는 것이 더 명확하게 전달될 것이다.
또한 위와 비슷하게 x[0]과 같이 특별한 값을 검색할 때 0을 통해 검색하면 특정 문서의 모든 0을 보고 어떤 의미인지 파악해야 해서 더 많은 시간이 걸릴 것이다(grep을 통해 0을 검색하는 것과 STATUS_VALUE를 검색했을 때 어떤 값이 문서에서 더 많이 등장할지 생각해보자)

인코딩을 피하라

간단하게 얘기하면 이번 내용은 변수 이름에 자료형 혹은 접두어 넣지 말자는 내용이다

String nameString;
String m_dsc

nameString의 자료형이 Name클래스로 변경되어도 nameString의 이름은 변경되지 않을 확률이 매우 높다.
m_dsc가 어떤 의미인지 모르겠지만, m_dsc도 마찬가지다.

네이밍 컨밴션

책에서는 클래스 이름 , 메서드 이름 로 설명한다.
간단하게 클래스는 명사, 메서드는 동사로 만들고 불명확한 단어 (Data, ~Info, ~Manager ...)는 피하자.

기발한 이름은 피하자

전라도에서는 거시기 라는 말을 가끔 쓴다.
맥락에 따라 이해되지만 어떤 말인지 전혀 모를 떄도 있다.
구어체나 속어를 변수명으로 사용하지 말자 그 말을 아는 사람만 알 수 있다.

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

추상적인 개념 하나에 단어 하나를 선택해 이를 사용하자.
예를 들어, 똑같은 메서드를 클래스마다 fetch, retrieve, ger으로 제각각 부르면 혼란스럽다. 어느 클래스에서 어느 이름을 썼는지 기억하기 어렵다.
본인이 많이 어려워하는 것 중 하나이다.

말장난을 하지 마라

한 단어를 두 가지 목적으로 사용하지 말자. 한 개념에 한 단어를 사용하라 했더니 예를 들어, 여러 클래스에 add라는 메서드가 생겼다. 모든 add 메서드의 매개변수와 반환값이 의미적으로 똑같다면 문제가 없겠지만, 일관성을 고려해 같은 맥락이 아닌데 add라는 이름을 사용하진 말자.

728x90

'이론' 카테고리의 다른 글

CleanCode - 주석  (1) 2024.01.01
CleanCode - 함수  (1) 2023.12.27
스프링 MVC 1 - MVC 패턴 개요  (0) 2022.08.11
스프링 MVC - 자바 백엔드 웹 기술 역사  (0) 2022.08.09
스프링 MVC 1 - HTML, HTTP API, CSR, SSR  (0) 2022.08.09
Comments