Railway reservations: one seat, several journeys a day
Published . By the DiagramDesk team.
Seat 41 in coach B is not one thing a railway sells. On the train that leaves on Monday it can be sold to someone going three stops and again to someone boarding where the first passenger gets off; on Tuesday it is on sale all over again. A railway model is right or wrong according to whether it can say that.
The dataStretchesCancellingUse casesData flowClassesMistakes
The data: train, run, stop, seat
A train here is a service with a number, such as the 07:40 from one city to another. It calls at a list of stations in order, and each call is a Stop with a sequence number and a departure time. The train runs on many days, and each day's running is a Run: that is what passengers are booked onto, because Monday's train and Tuesday's are different journeys with different people on them.
A booking belongs to one run and records where the travellers board and where they leave, as two stops. It covers one or more passengers travelling together, each with their own seat, and each seat is left empty while that passenger is on the waiting list. A passenger is numbered within the booking, so the booking's reference is part of the passenger's key and that line is solid, an identifying relationship. Every other line is dashed: the seat is only a foreign key on the passenger, and the other entities have ids of their own.
Two relationships run between Stop and Booking, one for boarding and one for leaving, and that is allowed: the same two entities can be related in more than one way, as long as each relationship has its own name. The coach and its seats hang off the train rather than the run in this version, on the assumption that a service always has the same make-up. A railway that changes coaches from day to day would move them to Run, and that is the kind of assumption to state in a report.
Selling a seat for part of the way
Because a booking has a boarding stop and a leaving stop, a seat is taken only for that stretch. Seat 41 held from stop 2 to stop 5 is free from stop 5 onwards, and free before stop 2. The check is the same overlap test a hotel uses for nights, with stop sequence numbers in place of dates: two stretches clash when each starts before the other ends. A passenger leaving at stop 5 and another boarding at stop 5 do not clash.
Getting this wrong is expensive in a real railway and visible in an assignment. A model that books a seat "on the train" sells it once per day, however far its passenger actually travels.
Cancelling, and what it sets off
The booking sequence is the one everybody draws. The cancellation is more instructive, because a cancelled booking hands its seats on. The sequence below cancels a two-person booking, confirms the refund to the passenger, and then offers the freed stretch to the waiting list, longest waiting first.
Two frames do different jobs here. The loop walks the waiting list; the opt frame, an optional section with a single guard, confirms a waiting booking only if one fits the freed seats. A waiting booking for stops 1 to 4 does not fit seats freed from stop 2, and is passed over, which is why the check asks about the stretch and not just the seat count. The passenger who cancelled gets their answer before any of that runs: they should not wait while the system reshuffles other people's seats.
Use cases
Passengers search, book, check their booking and cancel, online or at a counter, where a booking clerk does the same things on their behalf. The clerk has one job the passenger never sees: printing the list of passengers for each coach before the train leaves.
The booking clerk and the passenger share Book tickets and Cancel a booking, which is correct: two actors can take part in the same use case. Drawing the clerk as a specialised passenger would be wrong, because the clerk books for other people and does not travel on the ticket.
Data flow
The level 1 DFD splits the work into finding seats, booking, cancelling with reallocation, and loading the timetable. The timetable in D1 has one writer, process 4.0, which loads each new timetable from the planning office; the booking processes only read it. Leave 4.0 out and D1 becomes a store that is read but never written, one of the first things a marker looks for.
Classes
The class diagram puts the stretch logic on Run, as freeSeats(board, leave), because only a particular day's running knows which seats are taken. Each run keeps its own waiting list, drawn as composition. A train has at least two stops, which the multiplicity 2..* says precisely: a service that calls nowhere else cannot carry anyone anywhere.
The usual errors
- Seats attached to the train, not the day's run, so Monday's booking blocks Tuesday.
- A seat booked for the whole route when the passenger rides two stops.
- Origin and destination as columns on Train, which loses every stop in between.
- One passenger per booking, so a family travelling together gets four unrelated references.
- The waiting list as a separate table of copied details, instead of a status and a position on the booking itself.
- A cancellation that ends at the refund, leaving the freed seats unoffered.
Your brief may name a limit on passengers per booking, fare classes, or concessions for some travellers. Each is a rule on one of the entities above, not a new structure, and the report should say where each rule lives.
Keep going
- The hotel reservation system, the same overlap test with nights
- All the worked systems
- Draw your own sequence diagram