Capstone 6 — Hotel Reservation System¶
Scope: a term's work · Prerequisites: Modules 1–15
1. Problem statement¶
A hotel with several room types takes reservations for date ranges. A reservation occupies one room for a range of nights, and two reservations must never overlap on the same room.
The difficulty is time. A stay has an arrival and a departure, and the departure night is not occupied — an off-by-one that changes every availability answer in the system. Rates depend on the room type, the season, the length of stay and the number of guests. A guest may be upgraded when their type is full, and a cancellation may be free or charged depending on how close it is to arrival.
The system is used at the front desk, so answers have to be correct and immediate: "is a double room free from the 3rd to the 6th?" must not be answered by a scan of every reservation if the hotel is large.
2. Actors¶
| Actor | What they do | What the system owes them |
|---|---|---|
| Receptionist | Books, checks in, checks out, upgrades, cancels | Availability that is correct, and a price quoted before the booking is confirmed |
| Guest | Reserves, changes dates, cancels | A clear cancellation rule and a refund amount stated before confirming |
| Housekeeping | Sees which rooms to service today | A room list derived from today's stays |
| Manager | Sets rates and seasons | Rate changes without recompiling, and no existing reservation repriced |
3. Use cases¶
- Define room types and rooms: single, double, suite; each room of one type.
- Check availability for a room type over a date range.
- Make a reservation, quoting the total before confirming.
- Change a reservation's dates, if the new range is free.
- Cancel a reservation, with a charge determined by the notice given.
- Check a guest in and out.
- Upgrade a guest when their type is unavailable and a higher type is free, with the price rule stated.
- Price a stay: room type, season, length of stay, guest count.
- List today's arrivals, departures and rooms to service.
- Save and load everything; refuse a corrupted file with a line number and no partial state.
4. Suggested classes¶
| Class | Responsibility, in one sentence | Notes |
|---|---|---|
DateRange |
A half-open range of nights, with the arithmetic and overlap test | A value type: the heart of the domain's correctness |
RoomType |
A category of room with a nightly base rate and a capacity | Configuration carrier |
Room |
One physical room, of one type | Has a number; the unit that is reserved |
Guest |
A person with contact details | May be the holder of several reservations |
Reservation |
One room held for one date range, by one guest, at a quoted price | Owns its range; aggregates room and guest |
Season |
A named period with a rate multiplier | Asked about a date, not stored per reservation |
RatePolicy |
Turns room type, season, nights and guests into a total | Injected; the thing that varies |
CancellationPolicy |
Turns notice and a quoted price into a charge | Injected |
Occupancy |
Answers "which ranges are taken for this room" | Owns the booking index, so availability is not a full scan |
Hotel |
Coordinates operations and owns rooms and reservations | Where a booking becomes a transaction |
The class worth the most marks is DateRange and the Occupancy index behind it. Half-open ranges
(departure exclusive) remove the entire class of off-by-one bugs at a stroke, and the index is where the
module's complexity lesson lands: a linear scan of reservations is acceptable for twenty rooms and not for
five hundred, and the report should say what your structure makes cheap and what it makes expensive.
5. Relationships¶
Hotel ◆── vector<Room> composition
Hotel ◆── vector<Reservation> composition
Reservation ◆── DateRange composition: the range is part of the reservation
Reservation ────> Room association
Reservation ────> Guest association
Room ────> RoomType association: the type is shared configuration, not owned
Occupancy ◇── Reservation aggregation: it indexes reservations it does not own
Hotel ┈┈> RatePolicy dependency, injected
Hotel ┈┈> CancellationPolicy dependency, injected
Season ────> DateRange association: a season has a range
6. Design constraints¶
- A range is half-open: arrival inclusive, departure exclusive. Say so at the top of
DateRange, test it, and let every availability answer depend on it. - Two reservations may not overlap on one room, enforced in one place. Demonstrate it with a test that tries to book an overlapping stay and fails.
- Availability must not be a full scan in the design you submit — or if it is, the report must say what you would change and why you did not, with the measurement that would justify it.
- A quoted price is frozen on the reservation. A rate change does not reprice an existing booking — demonstrated.
- Rates and cancellation rules are policies, injected, so a season change is a value change.
- A cancellation charge is stated before the cancellation, so the guest can see what it will cost.
- Dates are values with arithmetic, not three integers passed around; and today's date is passed in, never read inside a rule.
- Format: documented text format with a version marker and an escape rule; ranges written unambiguously; a later-version file refused, not misread.
7. Milestones¶
| # | Milestone | Done when |
|---|---|---|
| 1 | Design | Diagram; the half-open range decision written down; the overlap rule located in one place; the availability structure chosen |
| 2 | Rooms and ranges | Room types and rooms; DateRange with arithmetic and overlap, tested at the boundaries |
| 3 | Booking | Make, change and cancel reservations; overlap and availability enforced with named refusals |
| 4 | Pricing | Rates from an injected policy, with seasons; a quote frozen on confirmation; cancellation charges |
| 5 | Persistence | Documented format; round trip preserving reservations and quotes; three hand-edited corruptions rejected with line numbers |
| 6 | Tests and report | Boundaries and failures asserted; a deliberate bug caught; the availability structure's cost stated; the reversal named with its cost |
8. Minimum requirements¶
- [ ] A
DateRangevalue type with arithmetic and an overlap test, half-open and documented - [ ] Room types, rooms and guests, with invariants enforced in their own classes
- [ ] Availability for a type and a range, correct at the boundaries (same-day arrival and departure)
- [ ] Make, change and cancel a reservation, each refusing invalid requests with a reason
- [ ] No overlap on one room — demonstrated by a test that tries
- [ ] Rates varying by type, season, nights and guests, from an injected policy; money in integer pence
- [ ] A quoted total frozen on the reservation, unchanged by a later rate change — demonstrated
- [ ] Cancellation charges by notice period, from an injected policy
- [ ] Persistence with a version marker and escape rule; a round trip preserving every reservation, including none at all
- [ ] Three hand-edited corruptions rejected with line numbers, leaving the loaded state untouched
- [ ] At least two patterns, each justified by a named requirement; one declined, with the reason
- [ ] Tests with assertions covering invariants, boundaries and failure paths
- [ ] No warnings with
-Wall -Wextra -Werror
9. Advanced requirements¶
- [ ] Upgrades when a type is full: a guest moved to a higher type at the original price, with the policy stated and tested
- [ ] A room-type capacity check for the number of guests, refused with a reason
- [ ] An availability index with the complexity of "is a type free for this range" stated and measured against a naive scan
- [ ] A new season added with no edits to existing code — the file count in the report
- [ ] Check-in and check-out, with a room's state derived from today's stays
- [ ] Group bookings of several rooms held together, cancellable as one
- [ ] A day sheet for housekeeping and reception, in a defined order
10. Testing requirements¶
- Invariants: no two reservations on one room overlap; a room's reservations are internally consistent; an arrival is never after its departure; a quoted price is unchanged by a later rate change
- Boundaries: a one-night stay; a stay ending the day another begins (allowed) and a stay starting the day another ends (allowed); a departure on the same day as arrival (zero nights, refused); a booking exactly at a season's edge; cancelling exactly at the free-cancellation deadline
- Failure paths: booking an occupied range; changing to an occupied range; cancelling an unknown reservation; a reservation with a departure before its arrival; loading a truncated file
- Round trip: reservations and quotes preserved exactly, including an empty hotel and a stay spanning a month boundary
- One deliberate bug (for example, treating the range as closed), caught by a boundary test, with the failing assertion kept
11. Extension ideas¶
- Waiting lists per room type, with notifications when a cancellation frees a range.
- Housekeeping status per room (clean, dirty, inspected), and the state machine that goes with it.
- A loyalty rate tier, added as a policy — count the files.
- Recurring group bookings for a conference, with the design question of whether a group is a reservation or a collection of them.
- Revenue reports per type and season, exported to CSV behind the same interface.
- A minimal occupancy forecast for a month, and the complexity of producing it from your index.
12. Evaluation checklist¶
- [ ] The diagram matches the declarations, including multiplicities
- [ ] The half-open range convention is documented, applied everywhere, and tested at both edges
- [ ] An overlapping booking is impossible — demonstrated by a test that tries
- [ ] Availability's cost in my structure is stated, with the alternative I rejected
- [ ] A rate change does not reprice an existing reservation — demonstrated
- [ ] Policies are injected, and two exist for rates and for cancellations
- [ ] A cancellation charge is visible before the cancellation happens
- [ ] The round trip preserves reservations and quotes, including an empty hotel — output pasted
- [ ] Three corruptions rejected with line numbers, leaving the loaded state untouched
- [ ] The suite fails when a deliberate bug is introduced
- [ ] One pattern considered and declined, in writing
- [ ] The report names the decision I would reverse and what reversing it would cost
Related: Capstone options · Projects and the rubric · Module 16 — Capstone · Module 14 — The STL with OOP