리팩터링 9장

데이터 조직화

9.1 변수 쪼개기

역할이 둘 이상인 변수가 있다면 쪼개야 한다. 역할 하나당 변수 하나다.

절차

  1. 변수를 선언한 곳과 값을 처음 대입하는 곳에서 변수 이름을 바꾼다.
  2. 가능하면 이때 불변으로 선언한다.
  3. 이 변수에 두 번째로 값을 대입하는 곳 앞까지의 모든 참조(이 변수가 쓰인 곳)를 새로운 변수 이름으로 바꾼다
  4. 두 번째 대입 시 변수를 원래이름으로 다시 선언한다.
  5. 테스트 한다.
  6. 반복한다. 매 반복에서 변수를 새로운 이름으로 선언하고 다음 번 대입 때까지의 모든 참조를 새 변수명으로 바꾼다. 이 과정을 마지막 대입까지 반복한다.

예시

function distanceTravelled(scenario, time) {
  let result;
  let acc = scenario.primaryForce / scenario.mass; // ⬅️
  let primaryTime = Math.min(time, scenario.delay);
  result = 0.5 * acc * primaryTime * primaryTime;
  let secondaryTime = time - scenario.delay;
  if (secondaryTime > 0) {
		let primaryVelocity = acc * scenario.delay;
    acc = (scenario.primaryForce + scenario.secondaryForce) / scenario.mass; // ⬅️
    result += primaryVelocity * secondaryTime + 0.5 * acc * secondaryTime * secondaryTime;
  }
  return result;
}

acc 변수에 값이 두 번 대입되는 부분을 쪼개보자.

function distanceTravelled(scenario, time) {
  let result;
  const primaryAcceleration = scenario.primaryForce / scenario.mass; // ✅
  let primaryTime = Math.min(time, scenario.delay);
  result = 0.5 * primaryAcceleration * primaryTime * primaryTime; // ✅
  let secondaryTime = time - scenario.delay;
  if (secondaryTime > 0) {
    let primaryVelocity = primaryAcceleration * scenario.delay; // ✅
    const secondaryAcceleration = (scenario.primaryForce + scenario.secondaryForce) / scenario.mass; // ✅
    result += primaryVelocity * secondaryTime + 0.5 * secondaryAcceleration * secondaryTime * secondaryTime; // ✅
  }
  return result;
}

9.2 필드 이름 바꾸기

데이터 구조는 프로그램을 이해하는 데 큰 역할을 한다. 클래스에서 게터와 세터 메서드의 이름은 레코드 구조체의 필드 이름만큼 중요하다.

절차

  1. 레코드의 유효 범위가 제한적이라면 필드에 접근하는 모든 코드를 수정한 후 테스트 한다. 이후 단계는 필요없다.
  2. 레코드가 캡슐화되지 않았다면 우선 레코드를 캡슐화한다.
  3. 캡슐화된 객체 안의 private 필드명을 변경하고, 그에 맞게 내부 메서드들을 수정한다.
  4. 테스트한다.
  5. 생성자의 매개변수 중 필드와 이름이 겹치는 게 있다면 함수 선언 바꾸기로 변경한다.

9.3 파생 변수를 질의 함수로 바꾸기

가변 데이터의 유효 범위는 가능한 한 좁혀야 한다.

그 방법 중 하나로, 값을 쉽게 계산해 낼수 있는 변수들을 모두 제거한다. 다만 예외가 있는데, 새로운 데이터 구조를 생성하는 변형 연산이라면 그대로 두는 것도 좋다.

  1. 데이터 구조를 감싸며 그 데이터에 기초하여 계산한 결과를 속성으로 제공하는 객체
  2. 데이터 구조를 받아 다른 데이터 구조로 변환해 반환하는 함수

절차

  1. 변수 값이 갱신되는 지점을 모두 찾는다. 필요하면 변수 쪼개기를 활용해 각 갱신 지점에서 변수를 분리한다.
  2. 해당 변수의 값을 계산해주는 함수를 만든다.
  3. 해당 변수가 사용되는 모든 곳에 어서션을 추가하여 함수의 계산 결과가 변수의 값과 같은 지 확인한다.
  4. 테스트한다.
  5. 변수를 읽는 코드를 모두 함수 호출로 대체한다.
  6. 테스트한다.
  7. 변수를 선언한고 갱신하는 코드를 죽은 코드 제거하기로 없앤다.

9.4 참조를 값으로 바꾸기

객체(데이터 구조)를 다른 객체(데이터 구조)에 중첩하면 내부 객체를 참조 혹은 값으로 취급할 수 있다. 참조로 다루는 경우에는 내부 객체는 그대로 둔 채 그 객체의 속성만 갱신하며, 값으로 다루는 경우에는 새로운 속성을 담은 객체로 기존 내부 객체를 통째로 대체한다.

필드를 값으로 다룬다면 내부 객체의 클래스를 수정하여 값 객체로 만들 수 있다. 값 객체는 불변이기 때문에 대체로 자유롭게 활용하기 좋다.

하지만 특정

9.5 값을 참조로 바꾸기

9.6 매직 리터럴 바꾸기

reference

좋은 웹페이지 즐겨찾기