Transactional / Concurrency• Patterns: Factory, Observer, Strategy
Airline Reservation
Hard
Problem Summary
Design an Airline Reservation System managing flight instances, multi-cabin inventory tiers (Economy, Business, First), temporary seat holds, PNR booking generation, and gate update alerts.
Functional Scope
- Search flights by origin, destination, and travel date with multi-leg segments.
- Multi-tier cabin seat inventory with dynamic yield pricing buckets.
- Temporary 15-minute inventory hold during passenger detail checkout.
- PNR (Passenger Name Record) generation upon payment verification.
- Observer pattern for flight schedule change and gate departure notifications.
Entity-Relationship (ER) Schema
Flight [1] --> [*] FlightInstance FlightInstance [1] --> [*] Seat Booking [1] --> [1] FlightInstance Booking [1] --> [*] Passenger
Design Approach
Apply optimistic locking with version checks or pessimistic row-locking on seat records to prevent double-booking under concurrent reservations.
Core Classes & Models
FlightInstance (FlightNumber, departureDate, aircraftSeatMap)Seat (SeatNo, CabinClass: ECONOMY, BUSINESS, FIRST, Status: AVAILABLE, HELD, BOOKED)Booking (PNR, passengers, seats, totalFare, BookingStatus)YieldPricingStrategy (Calculates dynamic fare based on bucket capacity remaining)NotificationObserver (Dispatches flight updates to passengers)
Code Blueprint
65 lines/**
* Low-Level Design: Airline Flight Reservation System
* Design Patterns Applied:
* - Factory Pattern: Flight and passenger ticket instantiation
* - Observer Pattern: Flight delay, gate change, and boarding broadcasts
* - Strategy Pattern: Dynamic flight fare and baggage fee calculation
*/
import java.util.*;
enum FlightStatus { SCHEDULED, BOARDING, DELAYED, DEPARTED }
// --- [DESIGN PATTERN: Strategy] Airline fare pricing ---
interface FareStrategy {
double calculateFare(double basePrice, int daysUntilFlight, boolean isPeakHoliday);
}
class DynamicFareStrategy implements FareStrategy {
@Override
public double calculateFare(double basePrice, int daysUntilFlight, boolean isPeakHoliday) {
double multiplier = (daysUntilFlight < 7) ? 1.5 : 1.0;
if (isPeakHoliday) multiplier *= 1.3;
return basePrice * multiplier;
}
}
// --- [DESIGN PATTERN: Observer] Flight departure alert listener ---
interface FlightUpdateListener {
void onFlightDelayed(String flightNumber, int delayMinutes, String newGate);
}
class PassengerNotificationService implements FlightUpdateListener {
@Override
public void onFlightDelayed(String flightNumber, int delayMinutes, String newGate) {
System.out.printf("✈️ [Passenger SMS] Flight %s delayed by %d mins. Proceed to Gate %s.%n",
flightNumber, delayMinutes, newGate);
}
}
class Flight {
private final String flightNumber;
private FlightStatus status = FlightStatus.SCHEDULED;
private final List<FlightUpdateListener> listeners = new ArrayList<>();
public Flight(String flightNumber) { this.flightNumber = flightNumber; }
public void addListener(FlightUpdateListener l) { listeners.add(l); }
public void delayFlight(int minutes, String newGate) {
this.status = FlightStatus.DELAYED;
for (FlightUpdateListener l : listeners) l.onFlightDelayed(flightNumber, minutes, newGate);
}
}
public class Main {
public static void main(String[] args) {
Flight flight = new Flight("AI-101");
flight.addListener(new PassengerNotificationService());
DynamicFareStrategy pricing = new DynamicFareStrategy();
double fare = pricing.calculateFare(200.0, 3, true);
System.out.printf("Dynamically Priced Ticket: $%.2f%n", fare);
flight.delayFlight(45, "B12");
}
}