본문 바로가기
Study-Book/클린 코드

의도를 분명히 밝혀라

by 어렵다어려웡 2022. 3. 23.

의도를 분명히 밝혀라

 

‘의도가 분명하게 이름을 지으라’고 말하기는 쉽다.

좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.

그러므로 이름을 주의깊게 살펴 더 나은 이름이 떠오르면 개선하자.

 

변수 나 함수 그리고 클래스 이름은 다음과 같은 굵직한 질문에 모두 답해야 한다.

변수의 존재이유? , 수행 기능은? , 사용 방법은?

 

따로 주석이 필요하다면 의도를 분명히 드러내지 못했다는 말이다.

int d; //경과 시간(단위: 날짜)

이름 d 는 아무 의미도 드러나지 않는다. 경과 시간 이나 날짜 라는 느낌이 안든다. 측정하려는 값과 단위를 표현하는 이름이 필요하다.

int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;

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

다음 코드는 무엇을 할까?

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을 어떻게 사용하는가?

 

위 코드 샘플에는 이와 같은 정보가 드러나지 않는다. 하지만 정보 제공은 충분히 가능했었다.

 

지뢰찾기 게임을 만든다고 가정하자.

그러면 theList 가 게임판이라는 사실을 안다. theList 를 gameBoard 로 바꿔보자.

 

  1. 게임판에서 각 칸은 단순 배열로 표현한다.
  2. 배열에서 0번째 값은 칸 상태를 뜻한다.
  3. 값 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;
}

코드의 단순성은 변하지 않았다. 연산자 수와 상수 수는 앞의 예제와 같으며 들여쓰기 단계도 동일하다.

 

그런데 코드는 더욱 명확해졌다.

 

한걸음 더 나아가, int 배열을 사용하는 대신에, 칸을 간단한 클래스로 만들어도 되겠다.

isFlagged 라는 좀 더 명시적인 함수를 사용해 FLAGGED 라는 상수를 감춰도 좋겠다.

 

새롭게 개선한 결과는 다음과 같다.

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

단순히 이름만 고쳤는데도 함수가 하는 일을 이해하기 쉬워졌다.

바로 이것이 좋은 이름이 주는 위력이다.