쾌락코딩

클린코드_의미있는 변수

|

코드를 읽는 시간 대 코드를 짜는 시간 비율이 10 대 1을 훌쩍 넘는다. 새 코드를 짜면서 우리는 끊임없이 기존 코드를 읽는다.

비율이 이렇게 높으므로 읽기 쉬운 코드가 매우 중요하다. 비록 읽기 쉬운 코드를 짜기가 쉽지는 않더라도 말이다. 하지만 기존 코드를 읽어야 새 코드를 짜므로 읽기 쉽게 만들면 사실은 짜기도 쉬워진다.

이 논리에서 빠져나갈 방법은 없다. 주변 코드를 읽지 않으면 새 코드를 짜지 못한다. 주변 코드가 읽기 쉬우면 새 코드를 짜기도 쉽다. 주변 코드를 읽기가 어려우면 새 코드를 짜기도 어렵다. 그러므로 급하다면, 서둘러 끝내려면, 쉽게 짜려면, 읽기 쉽게 만들면 된다.

의도를 분명하게 밝혀라

변수나 함수 그리고 클래스 이름은 다음과 같은 굵직한 질문에 모두 답해야 한다. 변수(혹은 함수나 클래스)의 존재 이유는? 수행 기능은? 사용 방법은? 따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 말이다.

의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워진다.

// 지뢰찾기 게임 중 일부
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. thiList에서 0번쨰 값이 어째서 중요한가?
  3. 값 4는 무슨 의미인가?
  4. 함수가 반환하는 리스트 list1을 어떻게 사용하는가?

더 좋은 아래와 같은 코드로 변경할 수 있다.

public List<Cell> getFlaggedCells() {
  List<Cell> flaggedCells = new ArrayList<Cell>();
  for (Cell cell : gameBoard)
    if (cell.isFlagged())
      flaggedCells.add(cell);
  return flaggedCells;
}

단순히 이름만 고쳤는데도 함수가 하는 일을 이해하기 쉬워졌다. 바로 이것이 좋은 이름이 주는 위력이다.

의미 있게 구분하라

연속적인 숫자를 덧붙이 이름(a1, a2, …, aN)은 의도적인 이름과 정반대다. 이런 이름은 아무런 정보를 제공하지 못하는 이름일 뿐이다. 저자 의도가 전혀 드러나지 않는다.

// javascript
function copyChars(a1, a2) {
  for (let i in a1) {
    a2[i] = a1[i]
  }
}

함수 이름으로 source와 destination을 사용한다면 코드 읽기가 훨씬 더 쉬워진다.

자기 기억력을 자랑하지 마라

문자 하나만 사용하는 변수 이름은 문제가 있다. 루프에서 반복 횟수를 세는 변수 i,j,k는 괜찮다.(l은 절대 안된다.) 단, 루프 범위가 아주 작고 다른 이름과 충돌하지 않을 때만 괜찮다. 루프에서 반복 횟수 변수는 전통적으로 한 글자를 사용하기 때문이다. 그 외에는 대부분 적절하지 못하다.

똑똑한 프로그래머와 전문가 프로그래머 사이에서 나타나는 차이점 하나만 들자면, 전문가 프로그래머는 명료함이 최고라는 사실을 이해한다. 전문가 프로그래머는 자신의 능력을 좋은 방향으로 사용해 남들이 이해하는 코드를 내놓는다.

클래스 이름

클래스 이름과 객체 이름은 명사나 명사구가 적합하다. Customer, WikiPage, Account, AddressParse 등이 좋은 예다. Manager, Proccessor, Data, Info 등과 같은 단어는 피하고, 동사는 사용하지 않는다.

메서드 이름

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

생성자를 중복정의(overload)할 때는 정적 팩토리 메서드를 사용한다. 메서드는 인수를 설명하는 이름을 사용한다.

// java
Complex fulcrumPoint = Complex.FromRealNumber(23,0);
//위의 코드가 아래 코드보다 좋다
Complex fulcrumPoint = new Complex(23,0);

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

추상적인 개념 하나에 단어 하나를 선택해 이를 고수한다. 예를 들어, 똑같은 메서드를 클래스마다 fetch, retreive, get으로 제각각 부르면 혼란스럽다.

말장난을 하지마라

add 메서드와 insert 또는 append는 맥락이 다르다. 분명히 메서드의 역할에 따라 적절하게 부여해야한다.

프로그래머는 코드를 최대한 이해하기 쉽게 짜야한다. 집중적인 탐구가 필요한 코드가 아니라 대충 훓어봐도 이애할 코드 작성이 목표다.

정리

책을 읽는 내내 좋은 코드, 읽기 좋은 코드에 대한 구체적인 개념이 들어섰다. 좋은코드, 읽기 좋은 코드는 독자가 마치 하나의 재미있는 소설을 읽는 듯이 쭈욱 읽혀나가는 코드다. 실제로 책의 많은 예제를 보니 메서드 이름, 변수 이름만 대충보아도 흐름이 보이고 맥락이 보이는 경험을 할 수 있었다. 협업하는 환경에서는 먼저 코드를 읽어야 코드를 짤 수 있으므로 코드의 시작은 코드를 읽는 것이다. 그 시작이 재미있는 소설처럼 읽힌다면 코드짜는게 더 즐거워 질 것 같다.

Comments