problemmediumoodood-for-movie-ticket-booking-system-like-bookmyshowood for movie ticket booking system like bookmyshowoodformovieticketbookingsystemlikebookmyshow

OOD - Movie Ticket Booking System

MediumUpdated: Jan 1, 2026

1. Problem Statement

Modern movie ticket booking systems revolutionize the cinema-going experience by enabling customers to browse showtimes, select preferred seats, and purchase tickets from the comfort of their homes, eliminating the need to queue at physical box offices. These platforms must manage complex operational workflows including real-time seat inventory across multiple cinema locations, concurrent booking requests from thousands of users, dynamic pricing strategies based on seat categories (regular, premium, recliner), show timings (matinee vs. evening), and special formats (IMAX, 3D, Dolby Atmos). The system needs to display accurate seat maps reflecting booked and available seats, process payments through multiple channels (credit cards, digital wallets, gift cards), apply promotional discount coupons, and generate e-tickets with QR codes for contactless entry while integrating with cinema hall management systems for real-time show updates.

The architectural complexity extends beyond simple seat reservation to encompass sophisticated search capabilities allowing users to filter movies by genre, language, rating, release date, theater location, and show timing preferences. The platform must handle various user personas: guests browsing movie catalogs without registration, registered customers with booking history and saved payment methods, front desk officers assisting walk-in customers with immediate bookings, and administrators managing movie schedules, show timings, hall configurations, and promotional campaigns. The system requires intelligent notification mechanisms to alert users about upcoming shows, new movie releases, booking confirmations, cancellation acknowledgments, and refund processing status while maintaining user preference profiles for personalized movie recommendations based on viewing history and genre preferences.

Critical challenges include preventing double-booking scenarios where two users simultaneously attempt to reserve the same seat, implementing timeout mechanisms to release temporarily held seats if payment isn't completed within a specified duration, managing cancellation workflows with automated refund calculations based on cancellation policies (full refund if canceled 24 hours before showtime, partial refund otherwise), handling show cancellations by cinemas requiring bulk refund processing for all booked tickets, and ensuring system scalability during peak booking periods such as movie premieres, festival releases, and advance booking windows. The platform must support multi-city operations with different cinema chains, varying seating capacities per hall, flexible pricing matrices, integration with third-party payment gateways for secure transactions, and compliance with data protection regulations for storing customer payment information and personal details.

2. System Requirements

We'll focus on the following set of requirements while designing the Movie Ticket Booking System:

Functional Requirements:

  1. The system should list all cities where affiliate cinemas are located
  2. Each cinema can have multiple halls, and each hall runs one movie show at a time
  3. Each movie will have multiple shows scheduled across different times and halls
  4. Users should be able to search for movies by title, language, genre, release date, rating, and city
  5. Once a movie is selected, the system should display all cinemas showing that movie with available showtimes
  6. Customers should be able to select a specific show at a cinema and proceed to book tickets
  7. The system should display the seating arrangement of the cinema hall with clear indication of seat types (regular, premium, recliner, accessible)
  8. Customers should be able to select multiple seats and distinguish between available, booked, and temporarily held seats
  9. The system should implement a seat-hold mechanism with a timeout (e.g., 10 minutes) to release seats if payment is not completed
  10. Customers should be able to apply discount coupons and gift cards to their bookings
  11. The system should support multiple payment methods: credit/debit cards, digital wallets, UPI, and cash (for front desk bookings)
  12. Upon successful payment, the system should generate an e-ticket with QR code and booking reference number
  13. The system should send notifications for new movies, booking confirmations, show reminders, and cancellation updates
  14. Customers should be able to cancel bookings and receive refunds based on cancellation policy (time before show)
  15. Admins should be able to add/remove movies, create/modify shows, manage cinema halls, and configure pricing
  16. Front desk officers should be able to book tickets on behalf of walk-in customers
  17. The system should maintain booking history for registered customers
  18. The system should prevent double-booking by ensuring no two customers can reserve the same seat concurrently

Non-Functional Requirements:

  1. Concurrency: Handle thousands of concurrent users during peak times (weekend evenings, new releases) without performance degradation
  2. Consistency: Ensure strong consistency for seat reservations using database transactions (SERIALIZABLE isolation level)
  3. Performance: Search results should load within 1 second; seat map rendering within 2 seconds
  4. Availability: 99.9% uptime with graceful degradation if payment gateway is temporarily unavailable
  5. Scalability: Support horizontal scaling to handle traffic spikes during blockbuster movie releases
  6. Security: PCI-DSS compliance for payment processing; encrypted storage of customer payment information
  7. Data Integrity: Atomic booking operations ensuring payment, seat reservation, and ticket generation occur together or not at all

3. Use Case Diagram

We have five main actors in our system:

  • 🎬 Admin: Manages cinema infrastructure (adds/removes movies, creates/cancels shows, configures halls and pricing, manages promotions)
  • 🎫 Front Desk Officer: Assists walk-in customers (books tickets at counter, processes cash payments, handles immediate seat modifications)
  • 👤 Customer: Registered users (searches movies, books tickets, cancels bookings, manages payment methods, views booking history)
  • 👥 Guest: Non-registered users (browses movie catalog, searches showtimes, must register to complete bookings)
  • 🤖 System: Automated services (sends booking confirmations, releases expired seat holds, processes refunds, sends movie recommendations)

Here are the top use cases for the Movie Ticket Booking System:

Movie Discovery & Information (All Users)

  • Search movies by title, language, genre, rating
  • Filter by city and cinema location
  • View movie details (synopsis, cast, duration, rating)
  • Check showtimes across cinemas

Booking Workflow (Customers & Front Desk)

  • Select movie and showtime
  • View seat availability with real-time updates
  • Choose seats from interactive seat map
  • Apply discount coupons and gift cards
  • Hold seats temporarily during checkout
  • Process payment (multiple methods)
  • Generate e-ticket with QR code

Booking Management (Customers)

  • View current and past bookings
  • Cancel bookings with refund calculation
  • Modify seat selection (if allowed)
  • Save favorite cinemas and preferences

Cinema Operations (Admin)

  • Add/remove movies from catalog
  • Create show schedules across halls
  • Configure hall seating layouts
  • Set pricing for different seat categories
  • Create promotional campaigns
  • Cancel shows with bulk refunds

Notifications (System)

  • New movie releases
  • Booking confirmations
  • Show reminders (2 hours before)
  • Cancellation acknowledgments
  • Refund processing updates
graph TB
    subgraph Actors
        Guest([Guest])
        Customer([Customer])
        FrontDesk([Front Desk Officer])
        Admin([Admin])
        System([System])
    end
    
    subgraph MovieDiscovery["Movie Discovery & Search"]
        SearchMovie["Search Movies"]:::searchUC
        FilterCity["Filter by City"]:::searchUC
        ViewDetails["View Movie Details"]:::searchUC
        CheckShowtimes["Check Showtimes"]:::searchUC
    end
    
    subgraph BookingWorkflow["Booking Process"]
        SelectShow["Select Show"]:::bookingUC
        ViewSeats["View Seat Map"]:::bookingUC
        SelectSeats["Select Seats"]:::bookingUC
        HoldSeats["Hold Seats Temporarily"]:::bookingUC
        ApplyCoupon["Apply Discount Coupon"]:::bookingUC
        ProcessPayment["Process Payment"]:::bookingUC
        GenerateTicket["Generate E-Ticket"]:::bookingUC
    end
    
    subgraph BookingMgmt["Booking Management"]
        ViewBookings["View Booking History"]:::mgmtUC
        CancelBooking["Cancel Booking"]:::mgmtUC
        ModifySeats["Modify Seat Selection"]:::mgmtUC
        SavePreferences["Save Cinema Preferences"]:::mgmtUC
    end
    
    subgraph AdminOps["Admin Operations"]
        AddMovie["Add/Remove Movies"]:::adminUC
        CreateShows["Create Show Schedule"]:::adminUC
        ConfigHall["Configure Hall Layout"]:::adminUC
        SetPricing["Set Pricing Strategy"]:::adminUC
        ManagePromo["Manage Promotions"]:::adminUC
        CancelShow["Cancel Show"]:::adminUC
    end
    
    subgraph Notifications["Notifications"]
        NewMovieNotif["New Movie Alert"]:::notifUC
        BookingConfirm["Booking Confirmation"]:::notifUC
        ShowReminder["Show Reminder"]:::notifUC
        CancelNotif["Cancellation Alert"]:::notifUC
        RefundNotif["Refund Status"]:::notifUC
    end
    
    %% Guest connections
    Guest --> SearchMovie
    Guest --> FilterCity
    Guest --> ViewDetails
    Guest --> CheckShowtimes
    
    %% Customer connections
    Customer --> SearchMovie
    Customer --> ViewDetails
    Customer --> SelectShow
    Customer --> ViewSeats
    Customer --> SelectSeats
    Customer --> ApplyCoupon
    Customer --> ProcessPayment
    Customer --> ViewBookings
    Customer --> CancelBooking
    Customer --> ModifySeats
    Customer --> SavePreferences
    
    %% Front Desk connections
    FrontDesk --> SelectShow
    FrontDesk --> ViewSeats
    FrontDesk --> SelectSeats
    FrontDesk --> ProcessPayment
    FrontDesk --> CancelBooking
    
    %% Admin connections
    Admin --> AddMovie
    Admin --> CreateShows
    Admin --> ConfigHall
    Admin --> SetPricing
    Admin --> ManagePromo
    Admin --> CancelShow
    
    %% System connections
    System --> HoldSeats
    System --> GenerateTicket
    System --> NewMovieNotif
    System --> BookingConfirm
    System --> ShowReminder
    System --> CancelNotif
    System --> RefundNotif
    
    %% Use case relationships
    ProcessPayment -.->|includes| ApplyCoupon
    ProcessPayment -.->|triggers| GenerateTicket
    SelectSeats -.->|triggers| HoldSeats
    CancelBooking -.->|triggers| RefundNotif
    CancelShow -.->|triggers| CancelNotif
    
    classDef searchUC fill:#e1f5ff,stroke:#0288d1,stroke-width:2px,color:#000
    classDef bookingUC fill:#fff3e0,stroke:#f57c00,stroke-width:2px,color:#000
    classDef mgmtUC fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px,color:#000
    classDef adminUC fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#000
    classDef notifUC fill:#e8f5e9,stroke:#388e3c,stroke-width:2px,color:#000

Class Diagram

Here are the main classes of the Movie Ticket Booking System:

  • Account: Admin will be able to add/remove movies and shows, as well as block/unblock accounts. Customers can search for movies and make bookings for shows. FrontDeskOffice can book tickets for movie shows.
  • Guest: Guests can search and view movies descriptions. To make a booking for a show they have to become a registered member.
  • Cinema: The main part of the organization for which this software has been designed. It has attributes like ‘name’ to distinguish it from other cinemas.
  • CinemaHall: Each cinema will have multiple halls containing multiple seats.
  • City: Each city can have multiple cinemas.
  • Movie: The main entity of the system. Movies have attributes like title, description, language, genre, release date, city name, etc.
  • Show: Each movie can have many shows; each show will be played in a cinema hall.
  • CinemaHallSeat: Each cinema hall will have many seats.
  • ShowSeat: Each ShowSeat will correspond to a movie Show and a CinemaHallSeat. Customers will make a booking against a ShowSeat.
  • Booking: A booking is against a movie show and has attributes like a unique booking number, number of seats, and status.
  • Payment: Responsible for collecting payments from customers.
  • Notification: Will take care of sending notifications to customers.

Detailed Class Explanations:

  • User/Account: Represents customers, admins, and front desk officers. Stores personal profile data (name, contact info, birth date, gender) used for confirmations and authentication. Account types differentiate permissions and capabilities.
  • Movie: Captures a film available for booking with attributes like title, description, language, genre, release date, and city. Links to multiple shows across different theaters and times.
  • Theater/Cinema: Represents the physical venue organization. Holds identification, address, and list of cinema halls. Enables location-based search and filtering.
  • CinemaHall: Individual screening rooms within a cinema with specific seating capacity and layout. Each hall can run one show at a time.
  • Show: Represents a specific screening of a movie at a particular time in a cinema hall. Links movie, hall, timing, and available seats.
  • CinemaHallSeat: Physical seat in a cinema hall with attributes like seat number, type (regular/premium/recliner), and row/column position.
  • ShowSeat: Instance of a cinema hall seat for a specific show. Tracks availability status, pricing for that show, and booking state. This is the entity customers actually reserve.
  • Booking: Encapsulates a ticket purchase with unique booking number, references to user and show, selected seats, total amount, payment status, and timestamps. Drives the entire reservation workflow.
  • Payment: Handles payment processing with support for multiple payment methods (cards, wallets, cash). Tracks transaction status and integrates with payment gateways.
  • Notification: Manages communication with users for booking confirmations, cancellations, reminders, and promotional alerts through email/SMS.
  • Address: Value object bundling location attributes (street, city, state, zip, country) for theaters and user profiles.
  • Enumerations: Define constrained domains for booking status, seat types, account status, and payment status ensuring type safety and validity.
classDiagram
    class Account {
        -String id
        -String password
        -AccountStatus status
        +resetPassword()
    }
    
    class Person {
        -String name
        -Address address
        -String email
        -String phone
        -Account account
    }
    
    class Customer {
        +makeBooking(booking)
        +getBookings()
    }
    
    class Admin {
        +addMovie(movie)
        +addShow(show)
        +blockUser(customer)
    }
    
    class FrontDeskOfficer {
        +createBooking(booking)
    }
    
    class Guest {
        +registerAccount()
    }
    
    class Movie {
        -String title
        -String description
        -int durationInMins
        -String language
        -Date releaseDate
        -String country
        -String genre
        -List~Show~ shows
        +getShows()
    }
    
    class Show {
        -int showId
        -Date startTime
        -Date endTime
        -CinemaHall playedAt
        -Movie movie
    }
    
    class Cinema {
        -String name
        -int totalCinemaHalls
        -Address address
        -List~CinemaHall~ halls
    }
    
    class CinemaHall {
        -String name
        -int totalSeats
        -List~CinemaHallSeat~ seats
        -List~Show~ shows
    }
    
    class CinemaHallSeat {
        -int hallSeatId
        -SeatType seatType
    }
    
    class ShowSeat {
        -int showSeatId
        -boolean isReserved
        -double price
    }
    
    class Booking {
        -String bookingNumber
        -int numberOfSeats
        -BookingStatus status
        -Show show
        -List~ShowSeat~ seats
        -Payment payment
        +makePayment(payment)
        +cancel()
        +assignSeats(seats)
    }
    
    class Payment {
        -double amount
        -String transactionId
        -PaymentStatus status
    }
    
    class City {
        -String name
        -String state
        -String zipCode
    }
    
    class Address {
        -String street
        -String city
        -String state
        -String zipCode
        -String country
    }
    
    class Catalog {
        -Map movieTitles
        +searchByTitle(title)
        +searchByLanguage(language)
        +searchByGenre(genre)
        +searchByReleaseDate(date)
        +searchByCity(city)
    }
    
    Person <|-- Customer
    Person <|-- Admin
    Person <|-- FrontDeskOfficer
    Person o-- Account
    Customer --> Booking : makes
    Booking --> Show : for
    Booking --> ShowSeat : reserves
    Booking --> Payment : processes
    Show --> Movie : screens
    Show --> CinemaHall : in
    Cinema --> CinemaHall : contains
    CinemaHall --> CinemaHallSeat : has
    CinemaHallSeat <|-- ShowSeat
    Cinema --> Address : located at
    City --> Cinema : has

Activity Diagrams

Make a booking: Any customer can perform this activity. Here are the steps to book a ticket for a show.

graph TD
    Start([Customer selects movie]) --> SearchCity[Search movies by city]
    SearchCity --> SelectMovie[Select movie]
    SelectMovie --> ViewTheaters[View theaters & showtimes]
    ViewTheaters --> SelectShow[Select specific show]
    SelectShow --> DisplaySeats[Display seat layout]
    DisplaySeats --> SelectSeats[Customer picks seats]
    SelectSeats --> CheckAvailability{All seats available?}
    CheckAvailability -->|No| NotifyUnavailable[Notify & refresh layout]
    NotifyUnavailable --> DisplaySeats
    CheckAvailability -->|Yes| HoldSeats[Lock seats temporarily]
    HoldSeats --> CreateBooking[Create pending booking]
    CreateBooking --> ApplyCoupon{Apply coupon/discount?}
    ApplyCoupon -->|Yes| ValidateCoupon[Validate coupon]
    ValidateCoupon --> ProceedPayment
    ApplyCoupon -->|No| ProceedPayment[Proceed to payment]
    ProceedPayment --> ProcessPayment[Process payment]
    ProcessPayment --> PaymentSuccess{Payment successful?}
    PaymentSuccess -->|No| ReleaseSeats[Release seat locks]
    ReleaseSeats --> NotifyFailure[Notify payment failure]
    NotifyFailure --> End1([End])
    PaymentSuccess -->|Yes| ConfirmBooking[Mark booking CONFIRMED]
    ConfirmBooking --> GenerateTicket[Generate e-ticket with QR code]
    GenerateTicket --> SendConfirmation[Send confirmation email/SMS]
    SendConfirmation --> End2([End])

Cancel a booking: Customer can cancel their bookings. Here are the steps to cancel a booking:

graph TD
    Start([Customer initiates cancellation]) --> ViewBookings[View booking history]
    ViewBookings --> SelectBooking[Select booking to cancel]
    SelectBooking --> CheckShowTime{Show time check}
    CheckShowTime -->|Less than allowed time| RejectCancel[Reject cancellation]
    RejectCancel --> NotifyReject[Notify cancellation not allowed]
    NotifyReject --> End1([End])
    CheckShowTime -->|Within allowed window| CalculateRefund[Calculate refund amount]
    CalculateRefund --> ConfirmCancel{Confirm cancellation?}
    ConfirmCancel -->|No| End2([End])
    ConfirmCancel -->|Yes| UpdateBooking[Mark booking CANCELED]
    UpdateBooking --> ReleaseSeats[Release reserved seats]
    ReleaseSeats --> ProcessRefund[Process refund]
    ProcessRefund --> UpdatePayment[Update payment status to REFUNDED]
    UpdatePayment --> SendNotification[Send cancellation confirmation]
    SendNotification --> End3([End])

Code

Here are the high-level definitions for the classes described above.

Java Implementation

Enums, data types, and constants:

public enum BookingStatus {
    REQUESTED, PENDING, CONFIRMED, CHECKED_IN, CANCELED, ABANDONED
}

public enum SeatType {
    REGULAR, PREMIUM, ACCESSIBLE, RECLINER, EMERGENCY_EXIT, VIP
}

public enum AccountStatus {
    ACTIVE, BLOCKED, BANNED, COMPROMISED, ARCHIVED, UNKNOWN
}

public enum PaymentStatus {
    UNPAID, PENDING, COMPLETED, FAILED, DECLINED, CANCELLED, ABANDONED, SETTLING, SETTLED, REFUNDED
}

public class Address {
    private String streetAddress;
    private String city;
    private String state;
    private String zipCode;
    private String country;
    
    public Address(String street, String city, String state, String zipCode, String country) {
        this.streetAddress = street;
        this.city = city;
        this.state = state;
        this.zipCode = zipCode;
        this.country = country;
    }
}

Account, Customer, Admin, FrontDeskOfficer, and Guest:

public class Account {
    private String id;
    private String password;
    private AccountStatus status;
    
    public Account(String id, String password, AccountStatus status) {
        this.id = id;
        this.password = password;
        this.status = status;
    }
    
    public void resetPassword() {
        // Implementation
    }
}

public abstract class Person {
    private String name;
    private Address address;
    private String email;
    private String phone;
    private Account account;
    
    public Person(String name, Address address, String email, String phone, Account account) {
        this.name = name;
        this.address = address;
        this.email = email;
        this.phone = phone;
        this.account = account;
    }
}

public class Customer extends Person {
    public Customer(String name, Address address, String email, String phone, Account account) {
        super(name, address, email, phone, account);
    }
    
    public void makeBooking(Booking booking) {
        // Implementation
    }
    
    public List<Booking> getBookings() {
        return new ArrayList<>();
    }
}

public class Admin extends Person {
    public Admin(String name, Address address, String email, String phone, Account account) {
        super(name, address, email, phone, account);
    }
    
    public void addMovie(Movie movie) {
        // Implementation
    }
    
    public void addShow(Show show) {
        // Implementation
    }
    
    public void blockUser(Customer customer) {
        // Implementation
    }
}

public class FrontDeskOfficer extends Person {
    public FrontDeskOfficer(String name, Address address, String email, String phone, Account account) {
        super(name, address, email, phone, account);
    }
    
    public void createBooking(Booking booking) {
        // Implementation
    }
}

public class Guest {
    public void registerAccount() {
        // Implementation
    }
}

Show and Movie:

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

public class Show {
    private int showId;
    private Date startTime;
    private Date endTime;
    private CinemaHall playedAt;
    private Movie movie;
    
    public Show(int id, CinemaHall playedAt, Movie movie, Date startTime, Date endTime) {
        this.showId = id;
        this.playedAt = playedAt;
        this.movie = movie;
        this.startTime = startTime;
        this.endTime = endTime;
    }
}

public class Movie {
    private String title;
    private String description;
    private int durationInMins;
    private String language;
    private Date releaseDate;
    private String country;
    private String genre;
    private List<Show> shows;
    
    public Movie(String title, String description, int durationInMins, String language,
                 Date releaseDate, String country, String genre) {
        this.title = title;
        this.description = description;
        this.durationInMins = durationInMins;
        this.language = language;
        this.releaseDate = releaseDate;
        this.country = country;
        this.genre = genre;
        this.shows = new ArrayList<>();
    }
    
    public List<Show> getShows() {
        return shows;
    }
}

Booking, ShowSeat, and Payment:

import java.util.List;

public class Booking {
    private String bookingNumber;
    private int numberOfSeats;
    private BookingStatus status;
    private Show show;
    private List<ShowSeat> seats;
    private Payment payment;
    
    public Booking(String bookingNumber, int numberOfSeats, BookingStatus status,
                   Show show, List<ShowSeat> seats, Payment payment) {
        this.bookingNumber = bookingNumber;
        this.numberOfSeats = numberOfSeats;
        this.status = status;
        this.show = show;
        this.seats = seats;
        this.payment = payment;
    }
    
    public void makePayment(Payment payment) {
        // Implementation
    }
    
    public void cancel() {
        // Implementation
    }
    
    public void assignSeats(List<ShowSeat> seats) {
        this.seats = seats;
    }
}

public class ShowSeat extends CinemaHallSeat {
    private int showSeatId;
    private boolean isReserved;
    private double price;
    
    public ShowSeat(int id, boolean isReserved, double price, int hallSeatId, SeatType seatType) {
        super(hallSeatId, seatType);
        this.showSeatId = id;
        this.isReserved = isReserved;
        this.price = price;
    }
}

public class Payment {
    private double amount;
    private String transactionId;
    private PaymentStatus status;
    
    public Payment(double amount, String transactionId, PaymentStatus status) {
        this.amount = amount;
        this.transactionId = transactionId;
        this.status = status;
    }
}

City, Cinema, CinemaHall and CinemaHallSeat:

import java.util.List;

public class City {
    private String name;
    private String state;
    private String zipCode;
    
    public City(String name, String state, String zipCode) {
        this.name = name;
        this.state = state;
        this.zipCode = zipCode;
    }
}

public class Cinema {
    private String name;
    private int totalCinemaHalls;
    private Address address;
    private List<CinemaHall> halls;
    
    public Cinema(String name, int totalCinemaHalls, Address address, List<CinemaHall> halls) {
        this.name = name;
        this.totalCinemaHalls = totalCinemaHalls;
        this.address = address;
        this.halls = halls;
    }
}

public class CinemaHall {
    private String name;
    private int totalSeats;
    private List<CinemaHallSeat> seats;
    private List<Show> shows;
    
    public CinemaHall(String name, int totalSeats, List<CinemaHallSeat> seats, List<Show> shows) {
        this.name = name;
        this.totalSeats = totalSeats;
        this.seats = seats;
        this.shows = shows;
    }
}

public class CinemaHallSeat {
    private int hallSeatId;
    private SeatType seatType;
    
    public CinemaHallSeat(int id, SeatType seatType) {
        this.hallSeatId = id;
        this.seatType = seatType;
    }
}

Search interface and Catalog:

import java.util.Date;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

public interface Search {
    List<Movie> searchByTitle(String title);
    List<Movie> searchByLanguage(String language);
    List<Movie> searchByGenre(String genre);
    List<Movie> searchByReleaseDate(Date releaseDate);
    List<Movie> searchByCity(String cityName);
}

public class Catalog implements Search {
    private Map<String, List<Movie>> movieTitles;
    
    public Catalog() {
        this.movieTitles = new HashMap<>();
    }
    
    @Override
    public List<Movie> searchByTitle(String title) {
        return movieTitles.get(title);
    }
    
    @Override
    public List<Movie> searchByLanguage(String language) {
        return new ArrayList<>();
    }
    
    @Override
    public List<Movie> searchByGenre(String genre) {
        return new ArrayList<>();
    }
    
    @Override
    public List<Movie> searchByReleaseDate(Date releaseDate) {
        return new ArrayList<>();
    }
    
    @Override
    public List<Movie> searchByCity(String cityName) {
        return new ArrayList<>();
    }
}

Python Implementation

Enums, data types, and constants: Here are the required enums, data types, and constants:

from enum import Enum


class BookingStatus(Enum):
    REQUESTED, PENDING, CONFIRMED, CHECKED_IN, CANCELED, ABANDONED = 1, 2, 3, 4, 5, 6


class SeatType(Enum):
    REGULAR, PREMIUM, ACCESSIBLE, SHIPPED, EMERGENCY_EXIT, OTHER = 1, 2, 3, 4, 5, 6


class AccountStatus(Enum):
    ACTIVE, BLOCKED, BANNED, COMPROMISED, ARCHIVED, UNKNOWN = 1, 2, 3, 4, 5, 6


class PaymentStatus(Enum):
    UNPAID, PENDING, COMPLETED, FILLED, DECLINED, CANCELLED, ABANDONED, SETTLING, SETTLED, REFUNDED = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10


class Address:
    def __init__(self, street, city, state, zip_code, country):
        self.__street_address = street
        self.__city = city
        self.__state = state
        self.__zip_code = zip_code
        self.__country = country

Account, Customer, Admin, FrontDeskOfficer, and Guest: These classes represent the different people that interact with our system:

from abc import ABC
from .constants import AccountStatus


# For simplicity, we are not defining getter and setter functions. The reader can
# assume that all class attributes are private and accessed through their respective
# public getter methods and modified only through their public methods function.


class Account:
    def __init__(self, id, password, status=AccountStatus.Active):
        self.__id = id
        self.__password = password
        self.__status = status

    def reset_password(self):
        None


# from abc import ABC, abstractmethod
class Person(ABC):
    def __init__(self, name, address, email, phone, account):
        self.__name = name
        self.__address = address
        self.__email = email
        self.__phone = phone
        self.__account = account


class Customer(Person):
    def make_booking(self, booking):
        None

    def get_bookings(self):
        None


class Admin(Person):
    def add_movie(self, movie):
        None

    def add_show(self, show):
        None

    def block_user(self, customer):
        None


class FrontDeskOfficer(Person):
    def create_booking(self, booking):
        None


class Guest:
    def register_account(self):
        None

Show and Movie: A movie will have many shows:

from datetime import datetime


class Show:
    def __init__(self, id, played_at, movie, start_time, end_time):
        self.__show_id = id
        self.__created_on = datetime.date.today()
        self.__start_time = start_time
        self.__end_time = end_time
        self.__played_at = played_at
        self.__movie = movie


class Movie:
    def __init__(self, title, description, duration_in_mins, language, release_date, country, genre, added_by):
        self.__title = title
        self.__description = description
        self.__duration_in_mins = duration_in_mins
        self.__language = language
        self.__release_date = release_date
        self.__country = country
        self.__genre = genre
        self.__movie_added_by = added_by

        self.__shows = []

    def get_shows(self):
        None

Booking, ShowSeat, and Payment: Customers will reserve seats with a booking and make a payment:

from datetime import datetime
from .cinema import CinemaHallSeat


class Booking:
    def __init__(self, booking_number, number_of_seats, status, show, show_seats, payment):
        self.__booking_number = booking_number
        self.__number_of_seats = number_of_seats
        self.__created_on = datetime.date.today()
        self.__status = status
        self.__show = show
        self.__seats = show_seats
        self.__payment = payment

    def make_payment(self, payment):
        None

    def cancel(self):
        None

    def assign_seats(self, seats):
        None


class ShowSeat(CinemaHallSeat):
    def __init__(self, id, is_reserved, price):
        self.__show_seat_id = id
        self.__is_reserved = is_reserved
        self.__price = price


class Payment:
    def __init__(self, amount, transaction_id, payment_status):
        self.__amount = amount
        self.__created_on = datetime.date.today()
        self.__transaction_id = transaction_id
        self.__status = payment_status

City, Cinema, CinemaHall and CinemaHallSeat: Each city can have many cinemas and each cinema can have many cinema halls:

class City:
    def __init__(self, name, state, zip_code):
        self.__name = name
        self.__state = state
        self.__zip_code = zip_code


class Cinema:
    def __init__(self, name, total_cinema_halls, address, halls):
        self.__name = name
        self.__total_cinema_halls = total_cinema_halls
        self.__location = address

        self.__halls = halls


class CinemaHall:
    def __init__(self, name, total_seats, seats, shows):
        self.__name = name
        self.__total_seats = total_seats

        self.__seats = seats
        self.__shows = shows


class CinemaHallSeat:
    def __init__(self, id, seat_type):
        self.__hall_seat_id = id
        self.__seat_type = seat_type

Search interface and Catalog: Catalog will implement Search to facilitate searching of products.

from abc import ABC


class Search(ABC):
    def search_by_title(self, title):
        None

    def search_by_language(self, language):
        None

    def search_by_genre(self, genre):
        None

    def search_by_release_date(self, rel_date):
        None

    def search_by_city(self, city_name):
        None


class Catalog(Search):
    def __init__(self):
        self.__movie_titles = {}
        self.__movie_languages = {}
        self.__movie_genres = {}
        self.__movie_release_dates = {}
        self.__movie_cities = {}

        def search_by_title(self, title):
            return self.__movie_titles.get(title)

        def search_by_language(self, language):
            return self.__movie_languages.get(language)

        # ...

        def search_by_city(self, city_name):
            return self.__movie_cities.get(city_name)

Concurrency

How to handle concurrency; such that no two users are able to book the same seat?

We can use transactions in SQL databases to avoid any clashes. For example, if we are using SQL server we can utilize Transaction Isolation Levels to lock the rows before we update them. Note: within a transaction, if we read rows we get a write-lock on them so that they can’t be updated by anyone else. Here is the sample code:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
 
BEGIN TRANSACTION;
 
    -- Suppose we intend to reserve three seats (IDs: 54, 55, 56) for ShowID=99 
    Select * From ShowSeat where ShowID=99 && ShowSeatID in (54, 55, 56) && isReserved=0 
 
    -- if the number of rows returned by the above statement is NOT three, we can return failure to the user.
    update ShowSeat table...
    update Booking table ...
 
COMMIT TRANSACTION;

‘Serializable’ is the highest isolation level and guarantees safety from Dirty, Nonrepeatable, and Phantoms reads.

Once the above database transaction is successful, we can safely assume that the reservation has been marked successfully and no two customers will be able to reserve the same seat.

Read JDBC Transaction Isolation Levels for details.

Comments