// Booking 클래스
class Booking {
constructor(show, date) {
this._show = show;
this._date = date;
}
get hasTalkback() {
return (this._premiumDelegate)
? this._premiumDelegete.hasTalkback
: this._show.hasOwnProperty('talkback') && !this.isPeakDay;
}
get basePrice() {
let result = this._show.price;
if (this.isPeakDay) result += Math.round(result * 0.15);
return (this._premiumDelegate)
? this._premiumDelegate.extendBasePrice(result);
: result;
}
get hasDinner() {
return (this._premiumDelegate)
? this._premiumDelegate.hasDinner
: undefined;
}
_bePremium(extras) {
this._premiumDelegate = new PremiumBookingDelegate(this, extras);
}
}
// 1. 생성자를 팩터리 함수로 바꿔서 생성자 호출 부분을 캡슐화 한다.
function createBooking(show, date) {
return new Booking(show, date);
}
function createPremiumBooking(show, date, extras) {
// 3. 새로운 위임을 예약 객체와 연결한다.
const result = new Booking(show, date, extras);
result._bePremium(extras);
return result;
}
// 클라이언트(일반 예약)
aBooking = createBooking(show, date);
// 클라이언트(프리미엄 예약)
aBooking = createPremiumBooking(show, date, extras);
// 2. 새로운 위임 클래스를 만든다.
class PremiumBookingDelegate {
constructor(hostBooking, extras) {
this._host = hostBooking;
this._extras = extras;
}
get hasTalkback() {
return this._host._show.hasOwnProperty('talkback');
}
get basePrice() {
return Math.round(this._host._privateBasePrice + this._extras.premiumFee);
}
extendBasePrice(base) {
return Math.round(base + this._extras.premiumFee);
}
get hasDinner() {
return this._extras.hasOwnProperty('dinner') && !this.isPeakDay;
}
}