2012. 5. 4. 06:00

변수와 가독성

출처: The Art of Readable Code (번역서: 읽기 좋은 코드가 좋은 코드다)

☞ 개발자 강추 서적입니다.


변수와 관련된 3가지 문제점들이 있으며,


1. The more variables there are, the harder it is to keep track of them all.

2. The bigger a variable’s scope, the longer you have to keep track of it.

3. The more often a variable changes, the harder it is to keep track of its current value.


이러한 이슈를 처리하는 방법은 다음과 같습니다.


Eliminate Variables

  • Useless Temporary Variables
  • Eliminating Intermediate Results
  • Eliminating Control Flow Variables


Shrink(Reduce) the Scope of Variables

  • Creating "Private" Variables
  • Moving Definitions Down

Prefer Write-Once Variables
  • const or final
  • immutable or permanent

예제입니다.  아래와 같은 텍스트 입력 필드를 가지는 웹페이지가 하나 있습니다.

<input type="text" id="input1" value="Dustin">
<input type="text" id="input2" value="Trevor">
<input type="text" id="input3" value="">
<input type="text" id="input4" value="Melissa">
...
id 는 input 으로 시작하며 1에서 부터 하나씩 증가합니다. 작성해야할 함수는 value 값이 비어 있는 input 을 찾아서 값을 입력하는 것입니다. 앞에서 소개했던 변수와 관련된 원칙들을 고려하지 않고 작성한 코드는 다음과 같습니다.
var setFirstEmptyInput = function (new_value) {
	var found = false;
	var i = 1;
	var elem = document.getElementById('input' + i);
	while (elem !== null) {
		if (elem.value === '') {
			found = true;
			break;
		}
		i++;
		elem = document.getElementById('input' + i);
	}
	if (found) elem.value = new_value;
	return elem;
};

기능을 제대로 수행하지만 이쁘지 않습니다. found, i, elem 변수가 함수 전체에 걸쳐서 여러번 사용되고 있습니다. 우선 found 와 같은 중간 결과값을 저장하는 변수를 제거해 보겠습니다.

var setFirstEmptyInput = function (new_value) {
	var i = 1;
	var elem = document.getElementById('input' + i);
	while (elem !== null) {
		if (elem.value === '') {
			elem.value = new_value;
			return elem;
		}
		i++;
		elem = document.getElementById('input' + i);
	}
	return null;
};

다음은 elem 변수를 살펴보겠습니다. 이 변수는 저장하는 값이 무엇인지 기억하기 쉽지 않게끔 매우 반복적으로 사용되었습니다. 이를 좀 더 개선해 보겠습니다.

var setFirstEmptyInput = function (new_value) {
	for (var i = 1; true; i++) {
		var elem = document.getElementById('input' + i);
		if (elem === null)
			return null; // Search Failed. No empty input found.
		if (elem.value === '') {
			elem.value = new_value;
			return elem;
		}
	}
};

이 코드에서 elem 의 범위가 루프의 안쪽에 국한되었으며 값이 한 번만 할당되는 변수임에 주목하세요. for 루프의 조건으로 true 를 사용하는 게 흔한 일이 아니지만, 그렇게 함으로써 i 의 정의와 i의 값을 변경하는 구문을 한 줄에 담을수 있습니다. 

☞ 전 이 예제에서 for 루프를 이용하여 임시 변수 i 를 사용하면서도 while(true) 효과를 주는 방식이 아주 맘에 듭니다.