# 03-22. 데이터 클래스


# ✋ Intro

  • 데이터 클래스란 데이터 필드게터/세터 메서드로만 구성된 클래스를 말한다.

    • 그저 저장 용도로만 쓰이다 보니 다른 클래스가 너무 깊이까지 함부로 다룰 때가 많다.
    • 이런 클래스에 public 필드가 있다면 누가 보기 전에 얼른 **'레코드 캡슐화하기'**로 숨기자.
    • 변경하면 안 되는 필드는 **'세터 제거하기'**로 접근을 원천 봉쇄한다.
  • 다른 클래스에서 데이터 클래스의 게터나 세터를 사용하는 메서드를 찾아서 **'함수 옮기기'**로 그 메서드를 데이터 클래스로 옮길 수 있는지 살펴보자.

    • 메서드를 통째로 옮기기 어렵다면 **'함수 추출하기'**를 이용해서 옮길 수 있는 부분만 별도 메서드로 뽑아낸다.
  • 데이터 클래스는 필요한 동작이 엉뚱한 곳에 정의돼 있다는 신호일 수 있다.

    • 다른 함수를 호출해 얻은 결과 레코드(데이터 객체)로는 동작 코드를 넣을 이유가 없다.
    • 대표적인 예로 **'단계 쪼개기'**의 결과로 나온 중간 데이터 구조가 있다.
    • 이런 데이터 구조는 (적어도 현실에서 활용되는 모습상으로는) 불변(immutable)이다.
    • 불변 필드는 굳이 캡슐화할 필요가 없고, 불변 데이터로부터 나오는 정보는 게터를 통하지 않고 그냥 필드 자체를 공개해도 된다.

# (1) 세터 제거하기

  • 세터 메서드가 있다고 함은 필드가 수정될 수 있다는 뜻이다.
    • 객체 생성 후에는 수정되지 않길 원하는 필드라면 세터를 제공하지 않아야 한다.
    • 그러면 해당 필드는 오직 생성자에서만 설정되며, 수정하지 않겠다는 의도가 명백해지고, 변경될 가능성이 봉쇄된다.
  • 해당 리팩토링 기법이 필요한 상황
    • 사람들이 무조건 접근자 메서드를 통해서만 필드를 다루려고 할 때
      • 세터를 제거해서 객체가 생성된 후에는 값이 바뀌면 안 된다는 뜻을 분명히 하는 것이 좋다.
    • 클라이언트에서 생성 스크립트를 사용해 객체를 생성할 때
      • 생성 스크립트란 생성자를 호출한 후 일련의 세터를 호출하여 객체를 완성하는 형태의 코드를 말한다.
      • 해당 세터들은 처음 생성할 때만 호출되리라 가정하지만 이런 경우에도 세터들을 제거하여 의도를 더 정확하게 전달하는 게 좋다.

  • 리팩토링 예시
// before

class Person {
  constructor(name, id) {
    this._name = name;
    this._id = id;
  }
    
  get name() {
    return this._name;
  }
    
  set name(arg) {
    this._name = arg;
  }
    
  get id() {
    return this._id;
  }
    
  set id(arg) {
    this._id = arg;
  }
}

const martin = new Person();
martin.name = '마틴';
martin.id = '1234';
// after
// 사람의 속성 중 이름은 객체를 생성한 뒤라도 변경될 수 있겠지만 id는 그러면 안 된다.
// 이 의도를 명확히 알리기 위해 id 세터를 없앤다.

class Person {
  // 최초 한 번은 ID를 설정할 수 있어야 하므로 생성자에서 ID를 받도록 한다.
  constructor(id) {
    this._id = id;
  }
    
  get name() {
    return this._name;
  }
    
  set name(arg) {
    this._name = arg;
  }
    
  get id() {
    return this._id;
  }
}

const martin = new Person('1234');
martin.name = '마틴';