์ด๋ฒ ๋ฆฌํฉํฐ๋ง์ ์์๋ ์ด์ ์์๋ค ๋ณด๋ค ํจ์ฌ ๊ธธ๋ค
1. ์์1 : ์๋ธ ํด๋์ค๊ฐ ํ๋์ผ ๋
๊ณต์ฐ ์์ฝ ํด๋์ค
//์์ฝ ํด๋์ค
class Booking {
constructor(show, date) {
this._show = show;
this._date = date;
}
get hasTalkBack() {//ํ๋ฆฌ๋ฏธ์์ผ ๊ฒฝ์ฐ, ์ค๋ฒ๋ผ์ด๋
//์ผ๋ฐ ์์ฝ์ ๊ณต์ฐ ํ ๊ด๊ฐ๊ณผ์ ๋ํ ์๊ฐ์ ์ฑ์๊ธฐ๊ฐ ์๋ ๋๋ง ์ ๊ณตํ๋ค.
return this._show.hasOwnProperty('talkback') && !this.isPeakDay;
}
get basePrice() {//ํ๋ฆฌ๋ฏธ์์ผ ๊ฒฝ์ฐ, ์ค๋ฒ๋ผ์ด๋
let result = this._show.price;
if (this.isPeakDay) {
result += Math.round(result * 0.15);
}
return result;
}
}
//์ถ๊ฐ ๋น์ฉ์ ๋ค์ํ๊ฒ ์ค์ ํ ์ ์๋ ํ๋ฆฌ๋ฏธ์ ์์ฝ์ฉ ์๋ธํด๋์ค
class PremiumBooking extends Booking {
constructor(show, date, extras) {
super(show, date);
this._extras = extras;
}
get hasTalkBack() {//์ค๋ฒ๋ผ์ด๋ฉ
//์กฐ๊ฑด์ด ํ๋ ์ ๊ฑฐ๋จ์ผ๋ก์จ ํญ์ ๊ด๊ฐ๊ณผ์ ๋ํ ์๊ฐ์ ๋ง๋ จํ๋ค.
return this._show.hasOwnProperty('talkback');
}
get basePrice() {
//์ํผํด๋์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ๋, ๊ทธ์ ์ถ๊ฐ ์๊ธ์ ๋ํ๋ ์์ผ๋ก ์ค๋ฒ๋ผ์ด๋ฉ
return Math.round(super.basePrice + this._extras.PremiumFee);
}
//์ํผํด๋์ค์๋ ์๋ ๊ธฐ๋ฅ์ ํ๋ฆฌ๋ฏธ์ ์์ฝ์์๋ง ์ ๊ณตํ๋ค
get hasDinner() {
return this._extras.hasOwnProperty('dinner') && !this.isPeakDay;
}
}
const booking = new Booking(show, date);
const PremiumBooking = new PremiumBooking(show, date, extras);
์์ ์์๋ ์์์ด ์ ๋ค์ด๋ง๋๋ค. ์๋ธ ํด๋์ค์ ๋ํ ์ง์ ์์ด๋ ๊ธฐ๋ฐ ํด๋์ค(์ํผ ํด๋์ค)๋ฅผ ์ดํดํ ์ ์๊ณ ,
์๋ธ ํด๋์ค๋ ๊ธฐ๋ฐ ํด๋์ค์ ๋ฌด์์ด ๋ค๋ฅธ์ง๋ฅผ ์ค๋ช ํ๋ ๋ฐฉ์์ผ๋ก ์ ์๋์๋ค.
์ค๋ณต๋ ์ค์ด๊ณ ์๋ธ ํด๋์ค๊ฐ ์ถ๊ฐํ ์ฐจ์ด๊ฐ ๋ฌด์์ธ์ง ๋ถ๋ช ํ๊ฒ ์๋ ค์ฃผ๊ณ ์๋ค.
๊ทธ๋ฌ๋ ์์์ ํ๋ฒ๋ง ์ฌ์ฉํ ์ ์๋ ๋๊ตฌ๋ก, ์์์ ์ฌ์ฉํด์ผ ํ ๋ค๋ฅธ ์ด์ ๊ฐ ์๊ธด๋ค๋ฉด
์์ ์ฝ๋์์ ํ๋ฆฌ๋ฏธ์ ์์ฝ์ ์์์ด ์๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํํํด์ผ ํ ๊ฒ์ด๋ค.
์ด๋ฐ ์ํฉ์ด๋ผ๋ฉด ๊ธฐ๋ณธ ์์ฝ์์ ํ๋ฆฌ๋ฏธ์ ์์ฝ์ผ๋ก (ํน์ ๊ฑฐ๊พธ๋ก) ์ ํํ ์ ์๊ฒํ๋ฉด ์ ์ฉํ๋ค)
์ด๋ฌํ ์๊ตฌ๊ฐ ์ปค์ง๋ฉด ์๋ธํด๋์ค๋ฅผ ์์์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ ์ข๋ค.
์์1 : ์์์ ์์์ผ๋ก ๋ฐ๊พธ๋ ์ ์ฐจ
(1) ์์ฑ์๋ฅผ ํฉํฐ๋ฆฌ ํจ์๋ก ๋ฐ๊ฟ์ ์์ฑ์ ํธ์ถ ๋ถ๋ถ์ ์บก์ํ
- ํด๋์ค Booking ์์์
static createBooking(show, date) {
return new Booking(show, date);
}
static createPremiumBooking(show, date, extras) {
return new PremiumBooking(show, date, extras);
}
const booking = Booking.createBooking(show, date);
const premiumBooking = Booking.createPremiumBooking(show, date, extras);
(2) ์ด์ ์์ ํด๋์ค๋ฅผ ์๋ก ๋ง๋ ๋ค.
์์ ํด๋์ค์ ์์ฑ์๋ ์๋ธ ํด๋์ค๊ฐ ์ฌ์ฉํ๋ ๋งค๊ฐ ๋ณ์์ ์์ฝ ๊ฐ์ฒด๋ก์ ์ญ์ฐธ์กฐ๋ฅผ ๋งค๊ฐ ๋ณ์๋ก ๋ฐ๋๋ค. ์ญ์ฐธ์กฐ๊ฐ ํ์ํ ์ด์ ๋ ์๋ธ ํด๋์ค ๋ฉ์๋ ์ค ์ํผํด๋์ค์ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ธฐ ๋๋ฌธ(์์์์๋ ์ฝ๊ฒ ์ฒ๋ฆฌ ๊ฐ๋ฅํ์ง๋ง, ์์์์๋ ์ญ์ฐธ์กฐ๊ฐ ์์ด์ผ ํ๋ค.)
- PremiumBookingDelegate
constructor(hostBooking, extras) {
this.host = hostBooking;
this.extras = extras;
}
(3) ์๋ก์ด ์์์ ์์ฝ ๊ฐ์ฒด์ ์ฐ๊ฒฐํ ์ฐจ๋ก.
ํ๋ฆฌ๋ฏธ์ ์์ฝ์ ์์ฑํ๋ ํฉํฐ๋ฆฌ ํจ์๋ฅผ ์์ ํ๋ฉด ๋๋ค.
- Booking ํด๋์ค
static createPremiumBooking(show, date, extras) {
const result = new Booking(show, date, extras);
result.#bePremium(extras);
return result;
}
#bePremium(extras) {
//์์ํ ์ ์๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ค
this.#premiumDelegate = new PremiumBookingDelegate(this, extras);
}
bePremium ๋ฉ์๋๋ ์ด๋ฆ ์์ ๋ฐ์ค์ด๋ #์ ๋ถ์ฌ ์ด ๋ฉ์๋๋ Booking์ ๊ณต๊ฐ ์ธํฐํ์ด์ค๊ฐ ๋์ด์๋ ์ ๋๋ค๋ ์๋๋ฅผ ๋ฐํ๋ค.
(๋ฐ๋ผ์, ๋ง์ฝ ์ด ๋ฆฌํฉํ ๋ง์ ๋ชฉ์ ์ด ์ผ๋ฐ ์์ฝ๊ณผ ํ๋ฆฌ๋ฏธ์ ์์ฝ์ ์ํธ ๋ณํํ ์ ์๊ฒ ํ๋ ๊ฒ์ด์๋ค๋ฉด pubilc์ด์ด๋ ๊ด์ฐฎ๋ค)
(3) ๊ตฌ์กฐ๊ฐ ๊ฐ์ถฐ์ก์ผ๋ ๊ธฐ๋ฅ์ ์ฎ๊ธธ ์ฐจ๋ก
๋จผ์ ํจ์ ์ฎ๊ธฐ๊ธฐ๋ฅผ ์ ์ฉํด ์๋ธ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์์์ผ๋ก ์ฎ๊ธด๋ค.
์ ๋ณด๊ธ์๋ฆฌ์์ ์ ๋์ํ๋๋ก ํ๊ธฐ ์ํด ์ํผํด๋์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ถ์ ๋ชจ๋ _host๋ฅผ ํตํ๋๋ก ๊ณ ์น๋ค.
- PremiumBookingDelegate
get hasTalkBack() {
return this.#host.#show.hasOwnProperty('talkback');
}
get basePrice() {
return Math.round(this.#host._privateBasePrice + this._extras.PremiumFee);
}
(4) ์๋ธํด๋์ค์๋ง ์กด์ฌํ๋ ๋ฉ์๋๋ฅผ ์์์ผ๋ก ์ฎ๊ธด๋ค.
get hasDinner() {
return this._extras.hasOwnProperty('dinner') && !this.#host.isPeakDay;
}
(5) Booking์ ๋ถ๋ฐฐ ๋ก์ง์ ์ถ๊ฐํ๋ค.
- ํด๋์ค Booking
get hasDinner() {
return this.#premiumDelegate
? this.#premiumDelegate.hasDinner
: undefined;
}
์ญ์ ์ , 'js์๋ ๊ฐ์ฒด์ ์๋ ์์ฑ์ ์ ๊ทผํ๋ ค ํ๋ฉด undefined๋ฅผ ๋ฐํํ๋ฏ๋ก ์์ ๊ฐ์ด ์ฒ๋ฆฌํจ. ๋ค๋ฅธ ๊ฐ์ฒด ์งํฅ ๋์ ์ธ์ด์๋ค๋ฉด ์๋ฌ๋ฅผ ๋์ก์ ๊ฒ์ด๋ค.'
(6) ๋ชจ๋ ๊ธฐ๋ฅ์ด ์ ๋์ํ๋์ง ํ ์คํธํ ๋ค์ ์๋ธํด๋์คํ๋ฅผ ์ญ์ ํ๋ค.
- ํด๋์ค PremiumBookingDelegate
class PremiumBookingDelegate {
#host;
#extras;
constructor(hostBooking, extras) {
this.#host = hostBooking;
this.#extras = extras;
}
์์1 : ์์์ ์์์ผ๋ก ๋ฐ๊พผ ๋ค์ ์ฝ๋
class Booking {
#show;
#date;
constructor(show, date) {
this.#show = show;
this.#date = date;
}
get hasTalkBack() {
return this.#delegatePremiumBooking
? this.#delegatePremiumBooking.hasTalkBack
: this.#show.hasOwnProperty('talkback') && !this.isPeakDay;
}
get basePrice() {
let result = this.#show.price;
if (this.isPeakDay) {
result += Math.round(result * 0.15);
}
return result;
}
get hasDinner() {
return this.#delegatePremiumBooking
? this.#delegatePremiumBooking.hasDinner
: undefined;
}
private #bePremium(extras) {
this.#delegatePremiumBooking = new PremiumBooking(this, extras);
}
public static createBooking(show, date) {
return new Booking(show, date);
}
public static createPremiumBooking(show, date, extras) {
const booking = new Booking(show, date);
booking.#bePremium(extras);
return booking;
}
}
class PremiumBooking {
#host;
#extras;
constructor(booking, extras) {
this.#host = booking;
this.#extras = extras;
}
get hasTalkBack() {
return this.#host._show.hasOwnProperty('talkback');
}
get basePrice() {
return Math.round(this.#host.basePrice + this.#extras.PremiumFee);
}
get hasDinner() {
return this.#extras.hasOwnProperty('dinner') && !this.#host.isPeakDay;
}
}
const booking = Booking.createBooking(show, date);
const PremiumBooking = Booking.createPremiumBooking(show, date, extras);
2. ์์2: ์๋ธ ํด๋์ค๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๋
๋... ๋ถ๋ ์กฐ์ ์ ์ํ์ฌ ๋ค์ ํฌ์คํ ์ ์ด์ด์ ๊ณ์ ์์ฑ...