읽을거리/리팩터링

06 기본적인 리팩터링 - 변수 이름 바꾸기

씨씨상 2024. 11. 6. 19:40

 

 

변수 이름 바꾸기

 

 

 

 

let a = height * width;

 

 

let area = height * witdh;

 

 

배경

명확한 프로그래밍의 핵심은 이름짓기다. 변수는 프로그래머가 하려는 일에 관해 많은 것을 설명해준다. 단, 이름을 잘 지었을 때만 그렇다. 사실 나는 이름을 잘못 지을 때가 많다. 고민을 충분히 하지 않아서거나, 개발을 더 하다 보니 문제에 대한 이해도가 높아지거나, 혹은 사용자의 요구가 달라져서 프로그램의 목적이 변해 그럴 때도 있다.

 

특히 이름의 중요성은 그 사용 범위에 영향을 많이 받는다. 한 줄짜리 람다식lambda expression에서 사용하는 변수는 대체로 쉽게 파악할 수 있다. 맥락으로부터 변수의 목적을 명확히 알 수 있어서 한 글자로 된 이름을 짓기도 한다. 마찬가지로 간단한 함수의 매개변수 이름도 짧게 지어도 될 때가 많다. 물론 자바스크립트와 같은 동적 타입 언어라면 나는 이름 앞에 타입을 드러내는 문자를 붙이는 스타일을 선호한다(가령 매개변수 이름을 aCustomer와 같이 짓는다).

 

함수 호출 한 번으로 끝나지 않고 값이 영속되는 필드라면 이름에 더 신경 써야 한다. 내가 가장 신중하게 이름 짓는 대상이 바로 이런 필드들이다.

 

 

절차

  1. 폭넓게 쓰이는 변수라면 변수 캡슐화하기를 고려한다.
  2. 이름을 바꿀 변수를 참조하는 곳을 모두 찾아서, 하나씩 변경한다.
    • → 다른 코드베이스에서 참조하는 변수는 외부에 공개된 변수이므로 이 리팩터링을 적용할 수 없다.
    • 변수 값이 변하지 않는다면 다른 이름으로 복제본을 만들어서 하나씩 점진적으로 변경한다. 하나씩 바꿀 때마다 테스트한다.
  3. 테스트한다.

 

 

예시

변수 이름 바꾸기의 가장 간단한 예는 임시 변수나 인수처럼 유효범위가 함수 하나로 국한된 변수다. 굳이 예시가 필요 없을 정도로 간단하다. 그저 변수를 참조하는 코드를 찾아서 하나씩 바꾸면 되며, 다 바꾼 뒤에는 테스트해서 실수한 부분은 없는지 확인한다.

 

함수 밖에서도 참조할 수 있는 변수라면 조심해야 한다. 코드베이스 전체에서 두루 참조할 수도 있다. 다음 변수에서 이야기를 시작해보자.

 

let tpHd = 'untitled';

 

어떤 참조는 다음과 같이 변수를 읽기만 한다.

 

result += `<h1>${tpHd}</h1>`;

 

값을 수정하는 곳도 있다고 해보자.

 

tpHd = obj['articleTitle'];

 

나는 이럴 때 주로 변수 캡슐화하기로 처리한다.

 

setTitle(obj['articleTitle']);
function title() { // tpHd 변수의 게터
  return tpHd;
}
function setTitle(arg) { // tpHd 변수의 세터
  tpHd = arg;
}

 

캡슐화 후에는 변수 이름을 바꿔도 된다.

 

let _title = 'untitled';
function title() {
  return _title;
}
function setTitle(arg) {
  _title = arg;
}

 

그런 다음 래핑 함수들을 인라인해서 모든 호출자가 변수에 직접 접근하게 하는 방법도 있지만, 나는 별로 내켜하지 않는 방식이다. 이름을 바꾸기 위해 캡슐화부터 해야 할 정도로 널리 사용되는 변수라면 나중을 위해서라도 함수 안에 캡슐화된 채로 두는 편이 좋다고 생각하기 때문이다.

 

함수를 인라인한다면 값을 얻을 때는 getTitle() 게터를 호출하고 변수 이름에는 밑줄(_)을 붙이지 않았을 것이다.

 

 

예시: 상수 이름 바꾸기

상수(또는 클라이언트가 볼 때 상수처럼 작용하는 대상)의 이름은 캡슐화하지 않고도 복제 방식으로 점진적으로 바꿀 수 있다. 상수가 다음처럼 선언되어 있다고 하자.

 

const cpyNm = '애크미 구스베리';

 

먼저 원본의 이름을 바꾼 후, 원본의 원래 이름(기존 이름)과 같은 복제본을 만든다.

 

const companyName = '애크미 구스베리';
const cpyNm = companyName;

 

이제 기존 이름(복제본)을 참조하는 코드들을 새 이름으로 점진적으로 바꿀 수 있다. 다 바꿨다면 복제본을 삭제한다. 나는 기존 이름을 삭제했다가 테스트에 실패하면 되돌리는 방식보다 (앞의 코드처럼) 새 이름으로 선언한 다음 기존 이름에 복사하는 방식이 조금이라도 쉽다면 후자를 선택한다.

 

이 방식은 상수는 물론, 클라이언트가 볼 때 읽기전용인 변수(가령 자바스크립트의 익스포트한 변수)에도 적용할 수 있다.

 

 

 

 

 

[출처]

리팩터링 2판 - 마틴 파울러

 

[정리]

변수 이름 바꾸는 리팩터링을 실행할 때는 변수 캡슐화하기처럼 역시 바꾸는 값을 독점하는 함수를 만든다. (get, set) 상수 이름을 바꿀 때는 먼저 원본 변수의 이름을 바꾼 후 원본 변수의 값을 참조하는 변수를 만든다.