Encapsulate Collection, ์ปฌ๋ ์ ์บก์ํ ํ๊ธฐ๋ฅผ ์์๋ณด์.
์์ฝ
์ฝ๋
class Person {
get courses() {return this._courses;}
set courses(aList) {this._courses = aList;}
}
class Person {
get courses() {return this._courses.slice();}
addCourse(aCourse) {}
removeCourse(aCourse) {}
}
๋ฐฐ๊ฒฝ
- ์์์ ๊ฐ๋ณ ๋ฐ์ดํฐ๋ ์บก์ํํ๋๊ฒ ์ข๋ค ํ๋ค.
- ๊ทธ๋ฌ๋ฉด ์ธ์ ์์ ๋๋์ง์ ๋ํ ๊ฒ์ ์ด๋์ ๋ ํต์ ํ ์ ์๋ค.
- ๊ทธ๋ฐ๋ฐ ์ค์ํ๊ธฐ ์ข์ ๋ถ๋ถ์ด ์ปฌ๋ ์ ์ด๋ค.
- ๋ ์ฝ๋์์ ํน์ ์ปฌ๋ ์ ์ ์ ๊ทผํ๋ ํจ์๊ฐ ์๋ค๊ณ ํ์.
- ์ผ๋จ ๊ฐ์ ธ๊ฐ๋๋ฐ, ๊ทธ ๊ฐ์ ธ๊ฐ ์ฝ๋ ์ ์ ์์๋ฅผ ๋ค๋ฅธ ํจ์์์ ๋ฐ๊ฟจ๋ค.
- ์ฐธ์กฐ๊ธฐ ๋๋ฌธ์ ์๋ณธ ๋ฐ์ดํฐ ์์ฒด๋ ๋ณ๊ฒฝ๋์ด ๋ฒ๋ฆฐ๋ค.
- ์ด๋ ๊ฒ ๋๋ฉด ์๋ณธ ๋ฐ์ดํฐ ์ ๊ทผ์ด ์์ ๋ก์ ์ด๋์ ๋ณ๊ฒฝ์ด ์ผ์ด๋ฌ๋์ง ์๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋๋ฒ๊น ์ด ์ด๋ ค์์ง๋ค.
- ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋ณต์ ๋ณธ์ ๋ฐํํ๊ฒ ๋ง๋ค์ด์ ๋ฌธ์ ๋ฐ์ ์์ฒด๋ฅผ ๋ง๋ ๊ฒ์ด๋ค.
- ๋ณดํต์ ๋ณต์ ํ๋ค๊ณ ์ฑ๋ฅ์ ํ๊ฐ ํฌ์ง ์๋ค.
- ์๋๋ฉด ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ๊ณตํ๊ฑฐ๋.
- ๋ช ์ฌํด์ผ ํ ๊ฒ์ ์ค๊ตฌ๋จ๋ฐฉ์ผ๋ก ๋ฐฉ์์ ๋ค๋ฅด๊ฒ ํ์ง ์๋ ๊ฒ์ด๋ค.
- ์ฝ๋๋ฒ ์ด์ค์์ ์ผ๊ด์ฑ์ ์ฃผ์ด ์ปฌ๋ ์ ํจ์ ๋์ ๋ฐฉ์์ ํต์ผํด์ผ ํ๋ค.
์ ์ฐจ
- ์ปฌ๋ ์ ์ ์บก์ํ ํ๋ค.
- ์ปฌ๋ ์ ์ ์์๋ฅผ ์ถ๊ฐ/์ ๊ฑฐํ๋ ํจ์๋ฅผ ์ถ๊ฐํ๋ค.
- ์ ์ ๊ฒ์ฌ๋ฅผ ์ํํ๋ค.
- ์ปฌ๋ ์ ์ ์ฐธ์กฐํ๋ ๋ถ๋ถ์ ๋ชจ๋ ์ฐพ์์, ์ปฌ๋ ์ ์ ์บก์ํํ ์ ๊ทผ์๋ฅผ ์ฌ์ฉํ๋๋ก ์์ ํ๋ค.
- ์ปฌ๋ ์ ๊ฒํฐ๋ฅผ ์์ ํด์ ์๋ณธ ๋ด์ฉ์ด ์๋ ๋ณต์ ๋ณธ์ ๋ฐํํ๋๋ก ํ๋ค.
- ํ ์คํธํ๋ค.
์์
class Person {
constructor(name) {
this._name = name;
this._courses = [];
}
get name() {return this._name;}
get courses() {return this._courses;}
set courses(aList) {this._courses = aList;}
}
class Course {
constructor(name, isAdvanced) {
this._name = name;
this._isAdvanced = isAdvanced;
}
get name() {return this._name;}
get isAdvanced() {return this._isAdvanced;}
}
// Client 1
numAdvancedCourses = aPerson.courses.filter(c => c.isAdvanced).length;
// Client 2
const basicCourseNames = readBasicCourseNames(filename);
aPerson.courses = basicCourseNames.map(name => new Course(name, false));
// Client 3
for (const name of readBasicCourseNames(filename)) {
aPerson.courses.push(new Course(name, false));
}
aPerson.courses
๋ ์๋ณธ ์ปฌ๋ ์ ์ ๋ฐํํ๋ค.- ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด๊ฑธ ๋ณ๊ฒฝํ๊ณ ์๋ Client 2, 3์์๋ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋์ด ๋ฒ๋ฆฐ๋ค.
- ์๋ณธ ๋ฐ์ดํฐ๋ฅผ ์ด๋ ํ ๋ฐฉ์์ผ๋ก๋ ๋ฐ์ผ๋ก ๋ฑ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ ๋๋ก๋ ์บก์ํ๊ฐ ๋์๋ค๋ณด๊ธฐ ์ด๋ ต๋ค.
class Person {
constructor(name) {
this._name = name;
this._courses = [];
}
get courses() {
return this._courses.slice();
}
set courses(aList) {
this._courses = aList.slice();
}
addCourse(aCourse) {
this._courses.push(aCourse);
}
removeCourse(aCourse, fnIfAbsent = () => {throw new RangeError();}) {
const index = this._courses.indexOf(aCourse);
if (index === -1) fnIfAbsent();
else this._courses.splice(index, 1);
}
}
// Client 3
for (const name of readBasicCourseNames(filename)) {
aPerson.addCourse(new Course(name, false));
}
- ์ผ๋จ add, remove๋ฅผ ๋ฉ์๋๋ก ์ ๊ณตํ์ฌ ๋ณ๊ฒฝํ ์ ์ฒ๋ฆฌ ์ฝ๋๋ฅผ ๋ด๋ถ๋ก ๊ฒฉ๋ฆฌ์์ผฐ๋ค.
- ๋ํ set, get์ ํ ์์๋ ์๋ณธ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ์ง ์๊ณ , ๋ณต์ ๋ณธ์ ๋ฐํํ๋๋ก ํ์๋ค.