[Refactoring] # 기본형을 객체로 바꾸기

mechaniccoder·2021년 10월 12일
0
post-thumbnail

프로젝트에는 단순한 정보들을 문자열이나 숫자로 표현하고 있을 것이다. 예를 들어, 감정들에 대한 데이터가 있다고 가정하고, 대부분 이를 사용할때는 문자열 리터럴로 함수 파라미터로 사용하고 있을 텐데 이를 객체로 만들어주자.

객체로 만들면 데이터에 대한 오퍼레이션을 쉽게 추가할 수 있다는 장점이 있다.

Code

class Order {
  constructor(data) {
    this.priority = data.priority;
  }
}

// client
highPriorityCount = orders.filter((o) => o.priority === "hight" || o.priority === "rush").length;

// 데이터를 다루기 전에는 먼저 캡슐화를 해주자.
class Order {
  //...
  get priority() {
    return this._priority;
  }
  set priority(aString) {
    this._priority = aString;
  }
}

class Priority {
  constructor(value) {
    this._value = value;
  }
  // 독자는 getter를 사용하기 보다는 클라이언트의 관점을 생각했다.
  // 클라이언트의 관점에서 문자열의 필드값을 요청하기 때문이다.
  toString() {
    return this._value;
  }
}

// Order 클래스를 업데이트 해주자.
class Order {
  // ...
  get priority() {
    return this._priority.toString();
  }
  set priority(aString) {
    this._priority = new Priority(aString);
  }
}

// 클라이언트의 입장에서 사용되는 예를 보자.
hightPriorityCount = orders.filter((o) => o.priority === "high" || o.priority === "rush").length;

// 클라이언트의 입장에서 사용되는 인터페이스를 좀 더 추상화해보자.
hightPriorityCount = orders.filter((o) => o.priority.higherThan(new Priority("normal"))).length;

// 위의 코드처럼 사용하기 위해서는 Priority의 클래스를 수정해줘야 한다.
class Priority {
  constructor(value) {
    if (value instanceof Priority) return value;

    if (Priority.legalValues().includes(value)) {
      this._value = value;
    } else {
      throw new Error(`[${value}] is invalid for [Priority]`);
    }
  }
  get value() {
    return this._value;
  }
  static legalValues() {
    return ["low", "normal", "hight", "rush"];
  }
  get _index() {
    return Priority.legalValues().findIndex((s) => s === this.value);
  }
  higherThan(other) {
    return this._index > other._index;
  }
}

class Order {
  constructor(data) {
    this._priority = data.priority;
  }
  get priority() {
    return this._priority;
  }
  set priority(aString) {
    this._priority = new Priority(aString);
  }
}

소감

실제로 필자도 프로젝트를 할 때 사용되는 다양한 primitive 데이터들을 다뤘다. 지금까지는 문자열 리터럴이나 숫자로 이 데이터들을 다뤘는데, 이번 섹션을 읽고 깨달음을 얻은 것 같다. 이러한 primitive 데이터들을 객체로 관리하여, 데이터에 로직이 추가될 때 메서드로 이를 용이하게 관리하는 방법을 사용해봐야겠다.

Reference

Refactoring: Improving the Design of Existing Code (2nd Edition) p251-255.

profile
세계 최고 수준을 향해 달려가는 개발자입니다.

0개의 댓글