Chapter09. 데이터 조직화

김신영·2023년 7월 22일
0

Refactoring

목록 보기
9/12
post-thumbnail

변수 쪼개기 (Split Variable)

Split Variable

image

참고

  • 변수에 값을 여러번 대입할 수 밖에 없는 경우
    • 루프 변수 (Loop Variable)
    • 수집 변수 (Collecting Variable)
  • 그 외 변수들은 값을 단 한번만 대입해야 한다.
    • 두 번 이상 대입된다면, 여러 가지 역할을 수행한다는 신호다.

절차

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

예시

  • Before
    let temp = 2 * (height + width);
    console.log(temp);
    temp = height * width;
    console.log(temp);
  • After
    const perimeter = 2 * (height + width);
    console.log(perimeter);
    const area = height * width;
    console.log(area);

필드 이름 바꾸기 (Rename Field)

Rename Field

image

절차

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

예시

  • Before
    class Organization {
      get name() {...}
    }
  • After
    class Organization {
      get title() {...}
    }

파생 변수를 질의 함수로 바꾸기 (Replace Derived Variable with Query)

Replace Derived Variable with Query

image

절차

  1. 변수 값이 갱신되는 지점을 모두 찾는다.
    • 필요하면 변수 쪼개기 (Split Variables)를 활용해 각 갱신 지점에서 변수를 분리한다.
  2. 해당 변수의 값을 계산해주는 함수를 만든다.
  3. 해당 변수가 사용되는 모든 곳에 Assertion을 추가하여 함수의 계산 결과가 변수의 값과 같은지 확인한다.
    • 필요하면 변수 캡슐화하기 (Encapsulate Variables)를 적용하여 Assertion이 들어갈 장소를 마련한다.
  4. 테스트한다.
  5. 변수를 읽는 코드를 모두 함수 호출로 대체한다.
  6. 테스트한다.
  7. 변수를 선언하고 갱신하는 코드를 죽은 코드 제거하기(Remove Dead Code)로 없앤다.

예시

  • Before
    get discountedTotal() {return this._discountedTotal;}
    set discount(aNumber) {
      const old = this._discount;
      this._discount = aNumber;
      this._discountedTotal += old - aNumber; 
    }
  • After
    get discountedTotal() {return this._baseTotal - this._discount;}
    set discount(aNumber) {this._discount = aNumber;}

참조를 값으로 바꾸기 (Change Reference to Value)

Change Reference to Value

반대 리팩터링: Change Reference to Value

참고

bliki: ValueObject

image

절차

  1. 후보 클래스가 불변인지, 혹은 불변이 될 수 있는지 확인한다.
  2. 각각의 Setter를 하나씩 제거한다.
  3. 이 값 객체의 필드들을 사용하는 equality 비교 메서드를 만든다.

예시

  • Before
    class Product {
      applyDiscount(arg) {this._price.amount -= arg;}
  • After
    class Product {
      applyDiscount(arg) {
        this._price = new Money(this._price.amount - arg, this._price.currency);
      }

값을 참조로 바꾸기

Change Value to Reference

image

반대 리팩터링: Change Value to Reference

절차

  1. 같은 부류에 속하는 객체들을 보관할 저장소를 만든다.
    • 이미 존재한다면, PASS
  2. 생성자에서 이 부류의 객체들 중 특정 객체를 정확히 찾아내는 방법이 있는지 확인한다.

예시

  • Before
    let customer = new Customer(customerData);
  • After
    let customer = customerRepository.get(customerData.id);

매직 리터럴 바꾸기

Replace Magic Literal

image

절차

  1. 상수를 선언하고 매직 리터럴을 대입한다.
  2. 해당 리터럴이 사용되는 곳을 모두 찾는다.
  3. 찾은 곳 각각에서 리터럴이 새 상수와 똑같은 의미로 쓰였는지 확인하여, 같은 의미라면 상수로 대체한 후 테스트한다.

예시

  • Before
    function potentialEnergy(mass, height) {
      return mass * 9.81 * height;
    }
  • After
    const STANDARD_GRAVITY = 9.81;
    function potentialEnergy(mass, height) {
      return mass * STANDARD_GRAVITY * height;
    }
profile
Hello velog!

2개의 댓글

comment-user-thumbnail
2023년 7월 22일

블로그를 통해 코드 리팩토링에 관한 여러 가지 방법을 알게 되어 정말 유익했습니다. 특히 '변수 쪼개기'와 '매직 리터럴 바꾸기'에 대한 설명이 인상 깊었습니다. 감사합니다.

1개의 답글