Author: Denis Tjia <denis@u.nus.edu>
Preface
The purpose of this portfolio is to document the contributions that I have made to a software engineering project, during my second year of study at the National University of Singapore.
About the Project
The project was structured to resemble an intermediate stage of a real life software project. We were tasked to implement enhancements to the software, and also ensure that the finished product can be easily taken over by other developers.
My team of five decided to remix the application to keep track of events and tasks, very much like a calendar application. Our application, named Horo, aims to allow efficient management and organization of daily events and tasks, for any busy student.
For this project, I was given a few critical roles:
-
Designing the overall code architecture.
-
Implementation of the
Logic
andModel
in Horo.
Major Contribution
What |
Design of |
---|---|
Why |
This feature serves to make it very simple for future developers to add new commands. It was also designed to be very extensible for developers to build upon it. |
Highlights |
|
Functional Code |
|
Test Code |
|
Credits |
Design Patterns: Elements of Reusable Object-Oriented Software (1994) by The "Gang of Four". |
Minor Contribution
What |
Implementation of |
---|---|
Why |
These commands allow the user to create, modify and delete events in Horo! |
Functional Code |
|
Test Code |
Other Contributions
Project Management |
|
---|---|
Community |
|
Tools |
Integrated a third party library JSONAssert, to help with JSON unit testing. #223 |
Code Contribution |
3. Features
Command Format for Horo
-
You can enter a command by typing the command name first followed by arguments of the command.
-
E.g.
command_name <argument1> <argument2>…
-
-
If you want to type an argument containing blank spaces, surround your sentence within quotation marks.
-
E.g.
"Buy Groceries"
-
E.g.
add_task "Buy Groceries"
-
-
Command parameters are prefixed by
--
, and they are optional.-
E.g.
--date 09/2019
-
E.g.
calendar --date 09/2019
-
-
Please take note that commands with extra arguments given are truncated.
-
E.g. The
calendar
command does not accept any arguments, therefore if you entercalendar 09/2019
,09/2019
will be silently discarded.
-
Command Format for this User Guide
-
Arguments are fully capitalized which are to be supplied by you.
-
E.g.
add_task TASK
-
-
Arguments suffixed with ellipsis (
…
) indicate that the argument can be entered zero or more times.-
E.g.
delete_task INDEX…
-
-
Parameters separated by a vertical bar
|
can be used interchangeably.-
e.g. given the command format
-d|--description DESCRIPTION
, the following inputs accomplish the same thing: -
--description "Buy Groceries"
-
-d "Buy Groceries"
-
3.2.2. Deleting Events
You may use the delete_event
command to delete one or more events from the calendar.
Command Format:
Command Parameters:
-
--tag TAG…
Examples:
-
delete_event 0
-
delete_event 0 1 2
: Deletes events 0, 1 and 2. -
delete_event --tag Birthday
: Deletes events tagged asBirthday
. -
delete_event --tag Birthday Rori
: Deletes events tagged asBirthday
andRori
. -
delete_event 0 1 2 --tag Birthday Rori
: Deletes events 0, 1 and 2 only if they have been tagged asBirthday
andRori
.
Figure 3. Index found on the top right of the event.
|
3.3 CommandManager Component
The CommandManager
class manages the addition and invoking of Commands
in Horo.
Referring to the diagram above, it performs the following operations:
-
Listen for user input in
onCommandInput()
. -
Pass the user input to
commandParser
, to obtain aCommand
. -
Execute the
Command
and obtain aUserOutput
. -
Notify all
userOutputListeners
about theUserOutput
.
To give a more concrete example of how CommandManager
functions, refer to the sequence diagram below of adding a task to Horo:
3.3.2 CommandParser
CommandParser
is trying to tokenize any command input into one command keyword, and zero or more command phrases.
(i.e. [keyword] [phrase] [phrase] [phrase] …
).
To understand how the FSM works, study the activity diagram below:
Design Considerations
Option 1 | Option 2 | |
---|---|---|
What |
Use |
Implement a FSM to break up command input into tokens. |
Difficulty |
Easy |
Moderate |
How |
Split the command input by whitespaces, into words. The first word will be the command keyword. All subsequent words will have to be joined into command phrases. |
Create a |
Evaluation |
I did not choose this option because: Joining words into command phrases can become quite complex, especially when introducing quotation marks. Additionally, it is difficult for future developers to maintain and extend logic like this. |
I chose this option because: A state machine is easy to understand and configure. A state machine can tokenize complex command inputs. This grants future developers the ability to parse more advanced command inputs. |
3.3.4 CommandBuilder
A CommandBuilder
is defined to be able to accept an arbitrary amount of command phrases, and eventually create a Command
using those phrases.
Referring to the diagram above, the definition the command is implemented in two methods:
-
defineCommandArguments()
-
defineCommandOptions()
…
To understand how CommandBuilder
works, study the activity diagram below:
Design Considerations
Option 1 | Option 2 | |
---|---|---|
What |
Each |
Each |
Difficulty |
Easy |
Moderate |
How |
Implement a utility class which can parse user input into arguments. Use this class in each command parser. |
Implement |
Evaluation |
I did not choose this option because: Each command parser will need to implement logic to use the utility class, handle argument checking and parsing errors. It is difficult for future developers to create, extend and test |
I chose this option because: Each Since all logic is in |
3.1. Architecture
The Architecture Diagram given above explains the high-level design of Horo. Given below is a quick overview of each component.
…
The rest of Horo is managed by seven components:
-
CommandManager
: Responsible for executing commands from the user. -
Ics
: Responsible for handling the importing and exporting of ICS files. -
ModelManager
: Responsible for reading and writing to the in-memory data of Horo. -
NotificationManager
: Responsible for sending notifications to the user. -
StorageManager
: Responsible for reading and writing the Model to an external disk. -
UiManager
: Responsible for managing the user interface (UI) of Horo. -
UndoRedoManager
: Responsible for tracking changes in ModelManager, and reverting its history when needed.
Most components follow the observer design pattern, to reduce tight coupling and increase cohesion. They implement these listeners:
-
CommandInputListener
: The component will be notified about command input from the user. -
ModelDataListener
: The component will be notified whenever the Model changes. -
UserOutputListener
: The component will be notified whenever a message needs to be displayed to the user.
3.4. ModelManager Component
The ModelManager
is responsible for the reading and writing of events and tasks in Horo.
The ModelManager
has three main functions:
-
Stores all events and tasks in a wrapper class
ModelData
. -
Notifies all
ModelDataListeners
whenever theModelData
changes. -
Allows any class with a reference to
ModelManager
to update the currentModelData
.
To give a more concrete example of how ModelManager
notifies its listeners, refer to the sequence diagram below of adding a task to Horo: