Meeting Scheduler
Booking a room is easy. Booking a room and making sure the six people invited to it don't already have something else at that time is the actual problem - a scheduler that only checks the room is only doing half its job.
Requirements
Functional
- An
Attendeehas aCalendarofMeetings. - Scheduling a meeting takes a room, a time range, and a list of attendees; it only succeeds if the room is free for that range and every attendee's calendar is free for that range.
- If any conflict exists, scheduling fails and reports which resource (room or attendee) caused it, rather than silently double-booking.
- A meeting can be cancelled, freeing the room and every attendee's calendar for that slot.
Non-functional
- Conflict checking must be a single well-tested overlap rule reused for both rooms and attendees, not two copies of similar-but-subtly-different interval logic.
- Checking a person's or room's free/busy status for a given range should be answerable without recomputing every meeting they've ever had from scratch each time (called out as a future index, kept simple here).
Design
Calendar is the one class that knows how to answer "is this range free" - both Room and
Attendee hold one, and MeetingScheduler never inspects a meeting list directly. Booking
a meeting is a two-phase check: gather every calendar involved (the room's plus each
attendee's), confirm all of them are free, and only then commit the meeting everywhere - so
a failed check never leaves the room booked while an attendee's calendar isn't, or vice
versa.
- 1One call names every resource the meeting needs.
- 2The room's calendar is checked first.
- 3Every attendee's calendar is checked the same way, before anything commits.
- 4Only once every check passed does the meeting get written to the room's calendar.
- 5And to each attendee's calendar - all-or-nothing, never partial.
Meeting itself is inert data - a time range, a room, and a list of attendees - with no
scheduling logic of its own. That logic belongs entirely to Calendar and
MeetingScheduler, so a Meeting can be handed around, serialized, or compared without
dragging any behavior along with it.
Class diagram
Code
Design decisions
Calendaris shared byRoomandAttendeerather than each having its own bespoke booking list. A room and a person need the exact same question answered - "is this range free, and if not, what conflicts" - so giving them the same class means the overlap rule is written and tested once, and a bug fix there fixes it for both.- Scheduling is check-everything-then-commit-everything, not check-and-commit per-resource. Committing to the room first and only then discovering attendee three is busy would leave the room reserved for a meeting that never actually happens. Checking every calendar before touching any of them is what keeps a failed booking from leaving partial state behind.
- Conflict reporting names the specific resource that failed. Returning a bare "conflict" boolean forces the caller to re-check everything themselves to find out what to reschedule around; returning which room or attendee blocked it is what makes the failure actionable instead of just a rejection.
- What's missing for a real system:
Calendar's free-check here is a linear scan of that person's meetings, which is fine for a handful of meetings a day but should be an interval tree once someone has years of history, and recurring meetings (daily standup, weekly sync) aren't modeled - they'd need their own expansion step before hitting this same conflict check.