CSE 332 Lab 5: OOP Design
Due by Wednesday December 12th at 11:59 pm
Final grade percentage: 20 percent - 15 percent implementation, 5 percent Readme
This lab is intended to extend your understanding and use of C++ object-oriented programming techniques, and to give you more experience using common design patterns.
To complete this lab, you will be given some starter code in your repository. You should build additional functionality from there, documenting your thought process for each implementation decision you make in your Readme. The project we will be working on is a Calendar Application(I know 330 already has a calendar project...sorry!), however the goal is to design the software to be very extensible. For this lab, your documentation will be worth much more than in previous labs. Make sure you think through your design decisions thoroughly and document them thoroughly as well. The code I’ve provided is a very bare bones calendar, with currently very little functionality. You will be adding functionality is this lab. Below is a brief description of the provided code.
1. The application makes use of the composite pattern. This allows objects to be stored in tree-like structures, creating hierarchical structures of objects(a year has 12 months, a month has days, etc.). The composite pattern also allows us to treat leaf objects(objects that do not have any children) and composite objects(objects that may contain children) identically, because all objects in the composite define the same interface. The abstract base class “DisplayableComponent” defines the interface that all calendar objects inherit from, including days, months, years, and the calendar itself. The majority of the concrete classes that define the “DisplayableComponent” interface can be found in calendarcomponents.h and calendarcomponents.cpp.
2. The application makes use of the builder pattern for managing the construction of a Calendar. This allows the Calendar to remain unaware of how its internal state is constructed, allowing different builders to be used to construct the calendar in varying ways. The abstract base class “CalendarBuilder” declares the interface that a builder must define. FullCalendarBuilder is a concrete class defining that interface. FullCalendarBuilder works by constructing the entire calendar at once.
3. The CalendarInterface class is the client using a Calendar object. The code is designed with separation of concerns in mind. CalendarInterface manages input/output from the user(the user interface). The calendar object stores the data of our Calendar, and the builder is responsible for managing the construction process of our calendar and adding new components to it.declares and defines the interface presented by a calendar. Currently, the CalendarInterface class is very simple. It displays the calendar and gives the user a few options like zooming in or out on a particular object in the calendar and that’s about it. Throughout the rest of this lab, you will be expanding on that functionality.
4. Designpatterns.cpp gives a main function that initializes a CalendarInterface object and calls into it, allowing for user interaction. You should not write any significant code in this file, although you may end up changing the string passed as an argument to the
For this lab, you may work individually or in a 2-person or 3-person group. If you choose to work in a group, you work within a single repository, but in the ReadMe.txt file you then must:
(1) indicate who the members of the group are, and
(2) explain in some detail how you divided up the work (reasonably) evenly between you in designing and implementing your lab solution - i.e., who did which parts, etc.
Part I - Resources and Guidelines:
1. The constructor, destructor, operator, accessor, and mutator method examples in the C++ classes lecture slides give an overview of the kind of class syntax and structure you may need for this lab.
2. The examples on C++ subclassing and inheritance polymorphism in these slides also may be useful for thinking about how to structure your classes. Reviewing chapters 12, 13, and 15 from [LLM] can certainly be helpful as well.
3. Reviewing chapter 1 from [GHJV] can be helpful in thinking about different ways to create flexible, extensible code. Particularly, reviewing encapsulation, interface inheritance, composition, and delegation may be useful. Chapters 2 - 5 should be very useful as references when thinking about which design patterns may be applicable to problems you may encounter in your work, and thinking about the benefits of one pattern over another.
4. Please review the CSE 332 Programming Guidelines, all of which may be relevant to this lab. Please follow them as you implement your solution.
Part II - Required Functionality:
Your Readme.txt file for this lab should include the typical information:
● Group member names
● Any errors, warnings you ran into while working
● Test cases you ran to test the functionality of your Calendar
In the Readme.txt file you will also find a series of questions that should be answered as well.
Below is a list of functional requirements that should be added to your Calendar application. You are required to implement all functionality in this list. Exactly how you choose to do that is up to you, but I will make some suggestions as we go. There will be questions in the Readme.txt file associated with each piece of added functionality, you must answer them thoughtfully.
NOTE: I have provided interfaces for particular classes. These are simply starting suggestions, you may change these interfaces if needed.
1. Implement functionality for creating and adding Events to the Calendar. Here are some requirements:
a. An Event has a name, and a date/time(of type struct tm), as well as anything else it may inherit from base classes.
b. Event objects can only be added to Days (DisplayableDay objects). Events should only be added to the day that the event occurs in.
c. Recurring and multi day events should be supported(recur every days, event lasts for days). Each day an event falls on should contain a shared_ptr to a unique Event object. You should not share the same event object between days.
d. Events may be created in future years as well (up to the number of years stored in the calendar). Events may not be created in years prior to the current year.
e. A day may contain multiple events. Those events should be sorted by their start time.
Things to think about and suggestions:
f. How can you determine what day an event occurs in?
g. What object or objects should be responsible for this? What objects contain the necessary information to determine this?
h. Should an event inherit from any of the given classes?
Question 1 in the Readme pertains to the above functionality.
1. Make the Calendar interactive. Each time the Calendar is displayed, a set of options should be given. The user should be prompted to choose an option, and that request should be handled appropriately. A user should be given options pertaining to the current object being displayed as well as a set of global options:
a. Global options(available each time the Calendar is displayed)
i. Create a new Event
1. Should be handled by prompting the user for information about the Event, creating an event, and adding it to the calendar
ii. Search for an Event by name
1. Should display details of the event if found by updating the current view of the Calendar to display the event
a. If multiple Events have the same name, a list of all Events with the matching name should be displayed. The user can then choose one to display.
2. If no event matches the name, a message should be printed to alert the user.
3. For full credit, this should be done efficiently. What STL containers can be useful here? There is no need to iterate through or search the entire calendar.
iii. Jump to a specific date and select the granularity to view in the calendar
Ex: a user may specify August 10th, 2018 and “day” as the granularity, the display should then update its current view to the DisplayableDay object representing August 10th, 2018. If the user specifies “month” as the granularity, the display should update its current view to the DisplayableMonth object containing the DisplayableDay object for August 10th in its component subtree.
a. If a month is the top level object being displayed:
i. Display a line containing the name of each weekday, evenly spaced from each other. Let each column be about 11 characters wide.
ii. For each week contained in the month:
1. Display a line containing the day of the month associated with each day in the week, aligned properly with its associated weekday printed in step i.
2. Display a line containing the name of the first Event contained in each day of the week, once again columns should be spaced evenly with the weekday names above. If an event name is longer than the column width allows, truncate the event name.
3. Repeat with the second event in each day on a new line. If at any point a Day does not contain anymore events, fill its column with spaces. Continue this process until all events of each day are printed
4. Output a blank line
The output for the first couple of weeks of the month should look like:
a. If a day is the top level object being displayed:i. Print the name of the weekday and the days date on a single lineii. Print the events contained in that day, 1 event per line. The event name and time should be printed. The events should be printed in sorted order
based on their time.
iii. Output for a day may look something like (you can display the time however you would like):
Monday 2/21/2018 0800 event 1
1200 event 2
1600 event 3
Updating the DisplayableComponent interface may be useful here. Particularly, you need to modify how display() behaves for a component depending on its depth from the current view.
Design patterns that may help here: Strategy, State, Visitor, Chain of Responsibility
Part III: Implement 2 of the following options: (Extra credit: 5 points - implement the 3rd) In your Readme, document which piece of functionality you chose to implement. Document how the chosen design pattern works, and how it is used to implement the specified functionality.
1. Implement functionality to merge one calendar into another. Each merged Calendar should be given a unique name (chosen by the user when specifying which text file to load and merge). The structure of the Calendar should not change in any way, only the Events of the Calendar should be merged in. When displayed, an Event should specify which calendar it is associated with. Any number of Calendars should be able to be merged into 1. For instance, we may merge 3 calendars together with names C1, C2, and C3. The output when a day is displayed may look something like: Monday 2/21/2018 0800 C1::Event11200 C2::Event11300 C1:: Event22000 C3::Event1 When an event is displayed directly, the Calendar it belongs to should be listed as well. For full credit you must use the Decorator design pattern.
2. Implement functionality to add a TODO list within a DisplayableDay object in the Calendar. You should use the singleton pattern to ensure that each Day has only a single TODO list. A TODO list contains some number of Tasks. Each Task has at a minimum a name. When a Day is displayed directly, a user should be able to:a. Add a TODO list to the day, if a TODO list does not already exist for that dayb. Zoom in on the TODO list if it existsc. A TODO list should be displayed below the events for a given day and marked
“TODO list” when displayed
d. When a user is currently displaying a TODO list, the user should be able to:
i. Add tasks to the TODO list
ii. Mark tasks as complete
iii. Each task should be displayed and marked with either “TODO” or “COMPLETE”
iv. A user does not need to be able to zoom in on a particular task
TODO list should not be displayed in any other view, only when a Day containing a TODO list is being displayed directly or the TODO list itself is being displayed directly.
Design Patterns to consider: Singleton, Strategy, Decorator
For full credit, the singleton pattern must be used to ensure only a single TODO list exists for each day.
3. Incremental builder: Currently the FullCalendarBuilder constructs the entire calendar at once, which allocates a lot of objects and uses a lot of memory. In this part, you will implement an incremental builder. The goal is to construct components of the calendar on demand as they are needed. Your IncrementalCalendarBuilder class should inherit from CalendarBuilder. Initially, only a Calendar object should be constructed along with the current year, month, and day(the day, month, and year associated with the current date). As the user zooms in/out or jumps to a particular date and granularity, components of the calendar should be constructed and added to the calendar as needed by the builder. A user should be able to zoom in to a child that does not exist yet, so you may need to update the zoom functions accordingly.
Decide if you are working alone or in a team of 2 or 3. Decide on a team name. One member of your team should accept the assignment link here and create a team for their group. Now, the other members of the group should visit the assignment link, select the correct team name, and accept the assignment. A repository will be created for your team that is pre populated with the starter code for lab 5. You should create a VS solution within the repository and add the provided code into the solution to get started.
Complete the additional functionality as described. Document your work as typical in the Readme.txt file associated with the project. Answer all additional question in the Readme.txt file as well. Commit and push your final code to Github. There may be a demonstration process soon after the due date. This will give you a chance to demonstrate the functionality you implemented to a TA directly. Details on this to come.