본문으로 건너뛰기
홈
기술
기술 전체
프로그래밍68
컴퓨터 과학63
AI48
웹 개발36
인프라33
데이터31
소프트웨어 공학18
소개
← 목록으로소프트웨어 공학 › 코드 품질 › 리팩터링

1. Mysterious Name (이해하기 힘든 이름)

목차

1. Mysterious Name (이해하기 힘든 이름)

깔끔한 코드에서 중요한 것 중 하나가 ‘좋은 이름’이다.

함수, 변수, 클래스, 모듈의 이름을 보고 역할과 쓰임새를 짐작할 수 있어야 한다.

  • 사용할 수 있는 Refactoring 기술
    • Change Function Declaration(함수 선언 변경하기)
    • Rename Variable(변수 이름 바꾸기)
    • Rename Field(필드 이름 바꾸기)

Change Function Declaration(함수 선언 변경하기)

(함수명, 메소드명 매개변수 추가, 매개변수 제거, 시그니처 변경)

  • 좋은 이름을 가진 함수는 함수가 어떻게 구현되었는지 코드를 보지 않아도 함수명을 보고 이해할 수 있다.
  • 좋은 이름을 찾아내는 방법 : 함수에 주석을 작성한 후 주석을 함수이름으로 만든다.
  • 함수의 매개변수
    • 함수 내부의 문맥을 결정(ex, 전화번호 formatting 함수)
    • 의존성을 결정(ex, Payment 만기일 계산 함수)

Rename Variable (변수 이름 바꾸기)

  • 더 많이 사용되는 변수 일 수록 그 이름이 중요
    • 람다식에서 사용하는 변수 vs 함수의 매개변수
  • Dynamic Type을 지원하는 언어에서는 타입을 이름에 넣기도한다.
  • 여러 함수에 걸쳐 쓰이는 필드 이름에는 더 많이 고민하고 이름을 짓는다.

Rename Field(필드 이름 바꾸기)

  • Record 자료구조의 필드 이름은 프로그램 전반에 걸쳐 참조될 수 있기 때문에 중요하다.
  • Record 자료구조 : 특정 데이터와 관련있는 필드를 묶어놓은 자료구조
  • 파이썬의 Dictionary, 또는 줄여서 dicts.
  • C#의 Record.
  • Java의 record는 14에서 미리 보기 기능으로 도입됐고, 16부터 정식 언어 기능이다. Oracle 문서를 참고한다.
  • 자바에서는 Getter, Setter 메소드 이름도 필드의 이름과 비슷하게 간주할 수 있다.

예제: 이름만 읽고 계산의 뜻을 알 수 있는가?

주문 금액을 계산하는 다음 코드에서 f, x, p, q만 보고는 어떤 금액인지 알기 어렵다. p의 단위가 원인지 센트인지도 알 수 없다.

// 변경 전
type Line = { p: number; q: number };

function f(x: Line[]): number {
  return x.reduce((n, v) => n + v.p * v.q, 0);
}

const t = f([{ p: 1200, q: 2 }]);

함수에 주석을 쓴다면 “주문 항목의 단가와 수량을 곱해 합계를 구한다”가 될 것이다. 그 문장을 함수 이름과 필드 이름으로 옮긴다.

// 변경 후
type OrderLine = { unitPriceWon: number; quantity: number };

function calculateOrderSubtotalWon(lines: OrderLine[]): number {
  return lines.reduce(
    (subtotal, line) => subtotal + line.unitPriceWon * line.quantity,
    0,
  );
}

const subtotalWon = calculateOrderSubtotalWon([
  { unitPriceWon: 1200, quantity: 2 },
]);

calculateOrderSubtotalWon은 무엇을 계산하는지와 단위가 무엇인지 알려 준다. 세금과 배송비를 포함하지 않는다면 total보다 subtotal이 더 정확하다. 반면 같은 화면의 아주 짧은 반복문에서 i처럼 범위가 좁고 관례가 분명한 이름까지 길게 늘릴 필요는 없다.

이 변경은 앞에 적은 세 기법을 함께 사용한다. 함수 선언을 바꿨다면 호출부 f(...)도 함께 갱신하고, Line.p 같은 필드 이름을 바꿨다면 객체를 생성·읽는 곳을 모두 찾아야 한다. JSON API나 저장된 데이터에 쓰는 필드라면 외부 사용자가 그 이름을 계약으로 사용 중일 수 있으므로, 내부 변수 이름을 바꾸는 것과 별도로 호환성 계획이 필요하다.

동작은 이름 변경 전후 모두 1200 × 2 = 2400이다. 리팩터링의 목적은 이 계산 결과를 바꾸지 않고 읽는 사람이 코드를 해석하는 시간을 줄이는 것이다. 이름을 바꾼 뒤 기존 계산 테스트와 호출부의 타입 검사를 실행해 의도치 않은 변경이 없는지 확인한다.

같은 카테고리의 글