7-2. 컬렉션 캡슐화하기
적용 시점
배열이나 객체를 직접 반환해야 하는 경우
클라이언트가 실수로 원본 객체를 변화시키는 경우
절차
아직 컬렉션을 캡슐화하지 않았다면 변수 캡슐화하기부터 한다.
컬렉션에 원소를 추가/제거하는 함수를 추가한다.
정적 검사를 수행
컬렉션을 참조하는 부분을 모두 찾는다. 컬렉션의 변경자를 호출하는 코드가 모두 앞에서 추가한 추가/제거 함수를 호출하도록 수정한다. 하나씩 수정할 때마다 테스트한다.
컬렉션 게터를 수정해서 원본 내용을 수정할 수 없는 복제본을 반환하게 만든다.
테스트한다.
예시
❌Before
class Person {
constructor({ name, nicknames }) {
this._name = name;
this._nicknames = [...nicknames];
}
get name() { return this._name; }
get nicknames() { return this._nicknames; }
set nicknames(nicknames) { this._nicknames = nicknames ; }
}
// 사고 사례 1. nicknames를 추가해야 되는데 실수로 세터를 이용해서 누구든 Person 클래스를 수정할 수 있다.
const nicknames = createBasicCourses(fileName);
aPerson.nicknames = nicknames;
// 사고 사례 2. 요건 몰랐지? 요렇게하면 컬렉션 수정됨
aPerson.nicknames.push('babo');
class
⭕After
class Person {
constructor({ name, nicknames }) {
this._name = name;
this._nicknames = [...nicknames];
}
get name() { return this._name; }
get nicknames() { return cloneDeep(this._nicknames); }
addNickname(nickname) {
this._nicknames.push(nickname);
}
}
// 1. 삽입하려면 무조건 addNicknames만 가능하다.
const basicCourses = createBasicCourses(fileName);
basicCourses.map((basicCourse) => aPerson.addNickname(basicCourse));
// 2. 요거는 nicknames가 복사본을 반환하니까 Person 컬렉션에 영향을 미치지 않는다.
aPerson.nicknames.push('babo');
Last updated