OOD - Movie Ticket Booking System
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:
- The system should list all cities where affiliate cinemas are located
- Each cinema can have multiple halls, and each hall runs one movie show at a time
- Each movie will have multiple shows scheduled across different times and halls
- Users should be able to search for movies by title, language, genre, release date, rating, and city
- Once a movie is selected, the system should display all cinemas showing that movie with available showtimes
- Customers should be able to select a specific show at a cinema and proceed to book tickets
- The system should display the seating arrangement of the cinema hall with clear indication of seat types (regular, premium, recliner, accessible)
- Customers should be able to select multiple seats and distinguish between available, booked, and temporarily held seats
- The system should implement a seat-hold mechanism with a timeout (e.g., 10 minutes) to release seats if payment is not completed
- Customers should be able to apply discount coupons and gift cards to their bookings
- The system should support multiple payment methods: credit/debit cards, digital wallets, UPI, and cash (for front desk bookings)
- Upon successful payment, the system should generate an e-ticket with QR code and booking reference number
- The system should send notifications for new movies, booking confirmations, show reminders, and cancellation updates
- Customers should be able to cancel bookings and receive refunds based on cancellation policy (time before show)
- Admins should be able to add/remove movies, create/modify shows, manage cinema halls, and configure pricing
- Front desk officers should be able to book tickets on behalf of walk-in customers
- The system should maintain booking history for registered customers
- The system should prevent double-booking by ensuring no two customers can reserve the same seat concurrently
Non-Functional Requirements:
- Concurrency: Handle thousands of concurrent users during peak times (weekend evenings, new releases) without performance degradation
- Consistency: Ensure strong consistency for seat reservations using database transactions (SERIALIZABLE isolation level)
- Performance: Search results should load within 1 second; seat map rendering within 2 seconds
- Availability: 99.9% uptime with graceful degradation if payment gateway is temporarily unavailable
- Scalability: Support horizontal scaling to handle traffic spikes during blockbuster movie releases
- Security: PCI-DSS compliance for payment processing; encrypted storage of customer payment information
- 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.