Hotel Reservation System
Design a hotel reservation system that supports searching available rooms by date range and room type, booking with pricing, modifying or cancelling reservations, and check-in/check-out at the property.
Clarifying questions
- Single property or a chain? Cross-property search?
- Pricing tiers — flat per room type, dynamic by occupancy/date, or a separate revenue management system?
- What's the cancellation policy model — flat, tiered by days-out?
- Are room assignments fixed at booking or only at check-in?
- Do we handle group bookings (block of rooms) differently?
Core requirements
- Search rooms by date range, room type, and occupancy.
- Book a room for a guest with a price quote and confirmation.
- Modify or cancel a reservation subject to policy.
- Check guests in (assigning a specific room) and out (finalizing charges).
- Prevent overbooking through atomic availability checks.
- Support multiple room types with different rates.
Canonical class breakdown
Hotel — Owns Rooms and exposes search/book operations against its inventory.
Room — Physical room with type, number, and floor; holds long-lived attributes, not pricing.
RoomType — Class of room (Standard, Suite) used for search and base pricing; many Rooms per type.
Reservation — Guest's booking covering a date range and a RoomType, with a price quote and status.
RoomInventory — Per-date availability counters by RoomType; the source of truth that prevents overbooking.
PricingEngine (interface) — Quotes a price for a (RoomType, dateRange, guest); concrete impls handle flat, seasonal, dynamic.
CancellationPolicy (interface) — Computes refund amount and penalty given when the cancellation is made relative to check-in.
Guest — Person identity with contact, loyalty status, and a history of Reservations.
Java sketchjava
// Java skeleton
enum RoomTypeCode { STANDARD, DELUXE, SUITE }
enum ReservationStatus { BOOKED, CHECKED_IN, CHECKED_OUT, CANCELLED }
class RoomType {
private final RoomTypeCode code;
private final int maxOccupancy;
private final BigDecimal baseRate;
}
class Room {
private final String roomNumber;
private final int floor;
private final RoomType type;
}
class Guest {
private final String guestId;
private final String name;
private final String contact;
private String loyaltyTier;
}
class DateRange {
private final LocalDate checkIn;
private final LocalDate checkOut;
public List<LocalDate> nights() { ... }
}
class RoomInventory {
// Per-date counters by RoomType — O(1) availability check
private final Map<LocalDate, Map<RoomTypeCode, Integer>> availableByDate;
public boolean isAvailable(RoomTypeCode type, DateRange range, int qty) { ... }
public void reserve(RoomTypeCode type, DateRange range) { /* atomic decrement */ }
public void release(RoomTypeCode type, DateRange range) { ... }
}
interface PricingEngine {
BigDecimal quote(RoomType type, DateRange range, Guest guest);
}
interface CancellationPolicy {
BigDecimal computeRefund(Reservation r, Instant cancelledAt);
}
class Reservation {
private final String reservationId;
private final Guest guest;
private final RoomType roomType;
private final DateRange range;
private final BigDecimal quote; // frozen at booking
private Room assignedRoom; // null until check-in
private ReservationStatus status;
}
class Hotel {
private final List<Room> rooms;
private final RoomInventory inventory;
private final PricingEngine pricing;
private final CancellationPolicy cancellation;
public List<RoomType> search(DateRange range, int occupancy) { ... }
public Reservation book(Guest g, RoomType type, DateRange range) { ... }
public void cancel(Reservation r) { ... }
public Room checkIn(Reservation r) { /* assign a Room of the type */ }
public BigDecimal checkOut(Reservation r) { ... }
}
Key decisions to defend
- Book against RoomType, assign Room at check-in — booking specific room numbers explodes the availability problem.
- Inventory is per-date counters per type, not a list of bookings to scan — overbooking prevention has to be O(1).
- PricingEngine and CancellationPolicy are both Strategy interfaces because revenue rules are the most-volatile area.
- Reservation stores the price quote, not a recompute; same logic as bookstore Orders.
- Use a transactional decrement on RoomInventory at confirm-time to avoid races on the last available room.
Likely follow-ups
- · Add multi-property search across a chain — where does the join happen?
- · Support overbooking by N% with auto-walk policy — what changes?
- · Group bookings of 30 rooms — same model or new entity?
Dive deeper
Reservations test whether you understand that 'a room' and 'a unit of capacity for sale' are different things. Strong designs sell against RoomType and only resolve to physical Room at check-in. The other test is concurrency: the moment you have date-ranged availability, you have a race condition, and interviewers want to see you reach for either per-date counters with atomic decrement or a proper transaction boundary.