nextvern
7/7/2019 - 3:56 PM

CodeSpitz 83_1

CodeSpitz 83_1

package com.sagwangho;

public class Audience {
    private Ticket ticket = Ticket.EMPTY;
    private Invitation invitation = Invitation.EMPTY;
    private Long amount;

    public Audience(Long amount) {
        this.amount = amount;
    }

    public void buyTicket(TicketSeller seller, Movie movie) {
        ticket = seller.getTicket(this, movie);
    }

    public boolean hasAmount(Long amount) {
        return this.amount >= amount;
    }

    public boolean minusAmount(Long price) {
        if (amount > this.amount) return false;
        this.amount -= amount;
        return true;
    }

    public Invitation getInvitation() {
        return invitation;
    }

    public void setInvitation(Invitation invitation) {
        this.invitation = invitation;
    }

    public void removeInvitation() {
        this.invitation = Invitation.EMPTY;
    }

    public Ticket getTicket() {
        return this.ticket;
    }
}
package com.sagwangho;

public class Invitation {
    final static public Invitation EMPTY = new Invitation(null, null);
    final private Theater theater;
    final private Movie movie;

    public Invitation(Theater theater, Movie movie) {
        this.theater = theater;
        this.movie = movie;
    }

    public Movie getMovie() {
        return movie;
    }
}
package com.sagwangho;

public class Main {

    public static void main(String[] args) {

        Movie movie1 = new Movie("강철비", 100L);
        Movie movie2 = new Movie("스파이더맨", 200L);
        Movie movie3 = new Movie("미드소마", 150L);

        Theater theater1 = new Theater(movie1, movie2);
        Audience audience1 = new Audience(0L);
        Audience audience2 = new Audience(350L);
        TicketOffice ticketOffice = new TicketOffice(0L);
        TicketSeller seller = new TicketSeller();

        theater1.setTicketOffices(ticketOffice);
        theater1.setTicket(ticketOffice, movie1, 10L);
        theater1.setTicket(ticketOffice, movie2, 10L);
        theater1.setInvitation(audience1, movie2);

        seller.setTicketOffice(ticketOffice);

        audience1.buyTicket(seller, movie1);
        audience1.buyTicket(seller, movie2);
        audience2.buyTicket(seller, movie2);

        boolean isOk11 = theater1.enter(audience1, movie1);
        boolean isOk12 = theater1.enter(audience1, movie2);
        boolean isOk21 = theater1.enter(audience2, movie2);
        boolean isOk22 = theater1.enter(audience2, movie3);


        Theater theater2 = new Theater(movie2, movie3);
        theater2.setTicketOffices(ticketOffice);

        System.out.println(isOk11);
        System.out.println(isOk12);
        System.out.println(isOk21);
        System.out.println(isOk22);
    }
}
package com.sagwangho;

public class Movie {

    final private String title;
    final private long fee;

    public Movie(String title, long fee){
        this.title = title;
        this.fee = fee;
    }

    Long getFee() {
        return fee;
    }
}
package com.sagwangho;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Theater {

    final private List<TicketOffice> ticketOffices = new ArrayList<>();

    private List<Movie> movies = new ArrayList<>();

    public Theater(Movie... movies) {
        this.movies.addAll(Arrays.asList(movies));
    }

    public void setTicketOffices(TicketOffice... ticketOffices) {
        for (TicketOffice ticketoffice : ticketOffices) {
            if (ticketoffice.contractTheater(this)) this.ticketOffices.add(ticketoffice);
        }
    }

    public void setTicket(TicketOffice ticketOffice, Movie movie, Long num) {
        if (!ticketOffices.contains(ticketOffice)) return;
        if (!movies.contains(movie)) return;
        while (num-- > 0) {
            ticketOffice.addTicket(new Ticket(this, movie));
        }
    }

    public void setInvitation(Audience audience, Movie movie) {
        audience.setInvitation(new Invitation(this, movie));
    }

    public boolean enter(Audience audience, Movie movie) {
        if (!movies.contains(movie)) return false;
        Ticket ticket = audience.getTicket();
        return ticket.isValid(this, movie);
    }
}
package com.sagwangho;

public class Ticket {
    final static public  Ticket EMPTY = new Ticket(null, null);
    final private Theater theater;
    final private Movie movie;
    private boolean isEntered = false;

    public Ticket(Theater theater, Movie movie) {
        this.theater = theater;
        this.movie = movie;
    }

    public boolean isValid(Theater theater, Movie movie) {
        if(isEntered || theater != this.theater || movie != this.movie || this == EMPTY){
            return false;
        } else {
            isEntered = true;
            return true;
        }
    }

    public Long getFee(){
        return movie.getFee();
    }

    public boolean screeningMovie(Movie movie){
        return this.movie == movie;
    }

}
package com.sagwangho;

import java.util.ArrayList;
import java.util.List;

public class TicketOffice {
    private Theater theater;
    private Long amount;
    private List<Ticket> tickets = new ArrayList<>();

    public TicketOffice(Long amount) {
        this.amount = amount;
    }

    public boolean contractTheater(Theater theater) {
        if (this.theater != null) return false;
        this.theater = theater;
        return true;
    }

    public void addTicket(Ticket ticket) {
        this.tickets.add(ticket);
    }

    public Ticket getTicketWithFee(Movie movie) {
        Ticket ticket = Ticket.EMPTY;
        int ticketSize = tickets.size();
        if (ticketSize == 0) return ticket;

        for (int i = 0; i < ticketSize; i++) {
            Ticket searchTicket = tickets.get(i);
            if (searchTicket.screeningMovie(movie)) {
                ticket = tickets.remove(i);
                amount += ticket.getFee();
                break;
            }
        }

        return ticket;
    }

    public Ticket getTicketWithNoFee(Movie movie) {
        Ticket ticket = Ticket.EMPTY;
        int ticketSize = tickets.size();
        if (ticketSize == 0) return ticket;

        for (int i = 0; i < ticketSize; i++) {
            Ticket searchTicket = tickets.get(i);
            if (searchTicket.screeningMovie(movie)) {
                ticket = tickets.remove(i);
                break;
            }
        }

        return ticket;
    }

    public Long getTicketPrice(Movie movie) {
        int ticketSize = tickets.size();
        if (ticketSize == 0) return 0L;

        for (Ticket searchTicket : tickets) {
            if (searchTicket.screeningMovie(movie)) {
                return searchTicket.getFee();
            }
        }

        return 0L;

    }
}
package com.sagwangho;

public class TicketSeller {
    private TicketOffice ticketOffice;

    public void setTicketOffice(TicketOffice ticketOffice) {
        this.ticketOffice = ticketOffice;
    }

    public Ticket getTicket(Audience audience, Movie movie){
        Ticket ticket = Ticket.EMPTY;
        Invitation invitation = audience.getInvitation();
        if(invitation != Invitation.EMPTY && invitation.getMovie() == movie){
            ticket = ticketOffice.getTicketWithNoFee(movie);
            if(ticket != Ticket.EMPTY) audience.removeInvitation();
        } else {
            Long price = ticketOffice.getTicketPrice(movie);
            if(price > 0 && audience.hasAmount(price)){
                ticket = ticketOffice.getTicketWithFee(movie);
                if(ticket != Ticket.EMPTY) audience.minusAmount(price);
            }
        }
        return ticket;
    }
}