Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Theater {
- constructor() {
- this._movies = new Set();
- this._movieFees = new Map();
- this._ticketOffices = new Set();
- }
- getFee(movie) {
- if (!this.isScreening(movie)) throw new Error('movie is not screening');
- return this._movieFees.get(movie);
- }
- setFee(movie, fee) {
- if (!this._movies.has(movie)) return;
- this._movieFees.set(movie, fee);
- }
- setMovies(movies) {
- for (const movie of movies) {
- this._movies.add(movie);
- }
- }
- isScreening(movie) {
- return this._movies.has(movie);
- }
- setTicketOffices(ticketOffices) {
- for (const ticketOffice of ticketOffices) {
- if (!ticketOffice.isContractWith(this)) throw new Error('notContractWithThisTheater');
- this._ticketOffices.add(ticketOffice);
- }
- }
- setTicket(ticketOffice, movie, num) {
- if (!this._ticketOffices.has(ticketOffice)) return;
- while (num-- > 0) {
- ticketOffice.addTicket(movie, new Ticket(this, movie));
- }
- }
- setInvitation(audience) {
- audience.setInvitation(new Invitation(this, 7000));
- }
- enter(audience) {
- const ticket = audience.getTicket();
- if (!ticket) return false;
- return ticket.isValid(this);
- }
- }
- class Movie {
- constructor(name) {
- this._name = name;
- }
- }
- class Ticket {
- constructor(theater, movie) {
- this._theater = theater;
- this._movie = movie;
- this._isEntered = false;
- }
- getFee() {
- return this._theater.getFee(this._movie);
- }
- isValid(theater) {
- if (this._isEntered || theater !== this._theater || !theater.isScreening(this._movie)) return false;
- this._isEntered = true;
- return true;
- }
- }
- class Invitation {
- constructor(theater, amount) {
- this._theater = theater;
- this._amount = amount;
- }
- getTheater() {
- return this._theater;
- }
- getAmount() {
- return this._amount;
- }
- }
- class TicketOffice {
- constructor(theater, amount) {
- this._theater = theater;
- this._amount = amount;
- this._tickets = new Map();
- }
- isValidInvitation(invitation) {
- return this._theater === invitation.getTheater();
- }
- isContractWith(theater) {
- return this._theater === theater;
- }
- addTicket(movie, ticket) {
- if (this._tickets.has(movie)) {
- const tickets = this._tickets.get(movie);
- this._tickets.set(movie, [...tickets, ticket]);
- } else {
- this._tickets.set(movie, [ticket]);
- }
- }
- getTicketWithFee(movie) {
- if (!this._tickets.has(movie)) return null;
- const ticket = this._getTicket(movie);
- if (!ticket) return null;
- this._amount += ticket.getFee();
- return ticket;
- }
- getTicketWithNoFee(movie) {
- if (!this._tickets.has(movie)) return null;
- return this._getTicket(movie);
- }
- _getTicket(movie) {
- const [ticket] = this._tickets.get(movie).splice(0, 1);
- return ticket ? ticket : null;
- }
- getTicketPrice(movie) {
- if (!this._tickets.has(movie)) return null;
- const tickets = this._tickets.get(movie);
- if (!tickets.length) return null;
- const [ticket] = tickets;
- return ticket.getFee();
- }
- }
- class TicketSeller {
- constructor() {
- this._ticketOffice = null;
- }
- setTicketOffice(ticketOffice) {
- this._ticketOffice = ticketOffice;
- }
- getTicket(audience, movie) {
- let ticket = null;
- const price = this._ticketOffice.getTicketPrice(movie);
- const invitation = audience.getInvitation();
- if (invitation !== null && this._ticketOffice.isValidInvitation(invitation)) {
- const invitationAmount = invitation.getAmount();
- const canGetTicketByInvitation = price > 0 && invitationAmount >= price;
- const canGetTicketByInvitationWithAudienceMoney =
- (price > 0 && invitationAmount < price) && (audience.hasAmount(price - invitationAmount));
- if (canGetTicketByInvitation) {
- ticket = this._ticketOffice.getTicketWithNoFee(movie);
- if (ticket !== null) audience.removeInvitation();
- } else if (canGetTicketByInvitationWithAudienceMoney) {
- ticket = this._ticketOffice.getTicketWithFee(movie);
- if (ticket !== null) audience.minusAmount(price - invitationAmount);
- }
- } else {
- if (price > 0 && audience.hasAmount(price)) {
- ticket = this._ticketOffice.getTicketWithFee(movie);
- if (ticket !== null) audience.minusAmount(price);
- }
- }
- return ticket;
- }
- }
- class Audience {
- constructor(amount) {
- this._amount = amount;
- this._ticket = null;
- this._invitation = null;
- }
- buyTicket(seller, movie) {
- this._ticket = seller.getTicket(this, movie);
- }
- hasAmount(amount) {
- return this._amount >= amount;
- }
- minusAmount(amount) {
- if (amount > this._amount) return false;
- this._amount -= amount;
- return true;
- }
- getInvitation() {
- return this._invitation;
- }
- removeInvitation() {
- this._invitation = null;
- }
- getTicket() {
- return this._ticket;
- }
- setInvitation(invitation) {
- this._invitation = invitation;
- }
- }
- function main() {
- const hongDaeCgv = new Theater();
- const endGame = new Movie('EndGame');
- const toyStory = new Movie('ToyStory');
- hongDaeCgv.setMovies([endGame, toyStory]);
- hongDaeCgv.setFee(endGame, 10000);
- hongDaeCgv.setFee(toyStory, 12000);
- const audience1 = new Audience(10000);
- const audience2 = new Audience(20000);
- const audience3 = new Audience(5000);
- const audience4 = new Audience(6000);
- const hongDaeCgvTicketOffice = new TicketOffice(hongDaeCgv, 0);
- const seller = new TicketSeller();
- hongDaeCgv.setTicketOffices([hongDaeCgvTicketOffice]);
- hongDaeCgv.setTicket(hongDaeCgvTicketOffice, endGame, 10);
- hongDaeCgv.setTicket(hongDaeCgvTicketOffice, toyStory, 3);
- hongDaeCgv.setInvitation(audience3);
- hongDaeCgv.setInvitation(audience4);
- seller.setTicketOffice(hongDaeCgvTicketOffice);
- audience1.buyTicket(seller, toyStory);
- audience2.buyTicket(seller, toyStory);
- audience3.buyTicket(seller, toyStory);
- audience4.buyTicket(seller, toyStory);
- const isOk1 = hongDaeCgv.enter(audience1);
- const isOk2 = hongDaeCgv.enter(audience2);
- const isOk3 = hongDaeCgv.enter(audience3);
- const isOk4 = hongDaeCgv.enter(audience4);
- console.log(isOk1); // false
- console.log(isOk2); // true
- console.log(isOk3); // true
- console.log(isOk4); // true
- }
- main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement