# 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 = '마틴';