There are several design decisions that you need to make instinctively when faced with a design problem, such as given to you on Exam 3. Throughout this document, all sentences enclosed by [...] show optional extensions that you might have thought about, but didn't have to follow-through on the exam because of time constraints. I have capitalized on the nouns that form the basis for my design exposition here.
A personal weekly PLANNER can store MEETINGs during an ordinary five-day (Monday-Friday) business week. Some meetings occupy a single time slot (i.e., Tuesday at 11:00 AM) while a multi-day meeting represents a set of time slots throughout the week (i.e., Monday-Tuesday-Thursday-Friday at 11:00 AM). Each meeting has a room location. A time slot consists of a starting time and an ending time. It must be impossible to add to the weekly planner a meeting whose time slot(s) conflict with an existing meeting in the planner.
Let's start with the decisions in order:
1. Create a class called Planner
This class holds the responsibility of the entire problem. You can add meetings to a planner. The planner knows if a proposed meeting conflicts with an existing one.
[when we need to display the schedule, the Planner will return an Iterator of all meetings; note for this Iterator to work, it would be REALLY useful to have a class to represent a Meeting!].
2. Do we need a class called Day?
When considering this concept, see if there would be any different functionality between a meeting held, say, on Monday or one held on Friday? In actuality, you quickly see that there is no difference. To continue this line of reasoning, if you included the class Day why would you not go further and create a class Hour? The essential point is that the Planner maintains a set of Meetings, which we focus on now.
3. Create a class called Meeting
This class encapsulates the meeting concept. There are many meetings within the schedule maintained by Planner, so the relationship between Planner and Meeting is 1:*;
4. What are the attributes of Meeting?
We see that each meeting is on a specific day, and occupies a time slot with a clear starting and ending time calculated by Hour:Minute so Seconds seem to be irrelevant. But we can't just assign startingTime and endingTime because there are single-day meetings and multi-day meetings. Hmmm.
5. Do we need a class to represent a TimeSlot?
This is one class that might be missed in the initial design phase. A timeslot simply represents a period with a known starting time (in terms of hours and minutes) and a known ending time (also in terms of hours and minutes). However, there are key functions needed regarding time slots, specifically, to see if a timeslot overlaps another timeslot. Based only on this last function, we most decidedly need a class TimeSlot.
So here is our initial pass:
![]() |
Fig. 1 Initial Design |
Planner has a 1:* relationship with Meeting. But when trying to understand the relationship between Meeting and TimeSlot we see that it could either be 1:1 or 1:* because of the single-day and multi-day meetings.
What are some bad things that we could do? We could add an attribute "boolean multiday" to the Meeting class and then have Meeting record the day(s) on which the meeting is held. However, while there appears to be no functional difference between a single-day meeting and a multi-day meeting, there is indeed a structural difference. We have actually identified our first inheritance opportunity, namely, to create a concept known as a Meeting which will be the base class for two derived classes
6. Create derived class SingleDay and MultiDay representing the two type of meetings
Given the problem as described, it is not clear whether the mult-day meeting must be held at the same timeslot on each day of the week that the meeting is scheduled, or whether it can hop around as needed. For this design, let's opt for simplicity and assume that the only difference is whether a meeting is on one day or up to five days.
![]() |
Fig. 2 Second Design |
One of the benefits of having a Meeting class is that we can produce the public method "add(Meeting m)" in Planner which leaves it up to the user of Planner to create the single day or multi-day meeting object before adding it into our schedule. Once again, the Planner to Meeting relationship is 1:*.
Constructors for SingleDay and MultiDay will handle the specific details of how to construct each meeting object, and there will be a inherited constructor for Meeting that will include start and end times. These constructors are typically not shown on the initial design so we can keep things clear.
We now only lack the core functionality of handling conflicting meetings.
7. Why do we need to do anything else to handle conflicts?
Planner must return 'false' when an add is requested with a meeting that conflicts with an existing one in the schedule. This capability cannot reside solely within Planner! Think about it this way: Why should planner be responsible for (a) finding the time slot information for two meetings; (b) understand which ones are multi-day vs. single-day; (c) understand the ways in which two time slots can overlap or not overlap. It would be a mistake, therefore, to have a method "conflicts(Meeting m)" within Planner. For entirely different reasons, it would be a mistake to have a method "conflicts()" in Planner because there are no parameters to this method to say how it should do its work!
So we need to distribute the conflict-checking logic. And we hit our first roadblock right away. Note that Meeting has the relationship with TimeSlot (start and end) but the Meeting derived class is the one that knows of the specific day. This decision is a bad one because it splits up the logic across two classes that should be encapsulated into one. So we need to move day into TimeSlot, and then this means we can simplify the relationship(s) between SingleDay and Multi-Day meetings and TimeSlot.
![]() |
Fig. 3 Third Design |
Now there is no need to specifically store day as an int, a boolean, or some other value. For maximum flexibility (and readability) we use String for day. The room, currently in Meeting, could actually be moved into the TimeSlot class, because the meeting could float from place to place. Finally, the Meeting 'overlap' method depends upon the 'timeslots' method which is an Iterator returned by the appropriate derived class (SingleDay or MultiDay) that returns the slots for that meeting. Once this is in place, then the Meeting class can simply check all timeslots in both meetings in pairwise fashion to check for conflicts.
Note that the start and end times within timeSlot are integers, representing number of minutes since 12:00 midnight. Thus a 9:00 AM meeting has start value of 540.