Overview
AddressBook - Level 3 is a desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 10 kLoC.
Summary of contributions
-
Major enhancement: added the ability to undo/redo previous commands
-
What it does: allows the user to undo all previous commands one at a time. Preceding undo commands can be reversed by using the redo command.
-
Justification: This feature improves the product significantly because a user can make mistakes in commands and the app should provide a convenient way to rectify them.
-
Highlights: This enhancement affects existing commands and commands to be added in future. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required changes to existing commands.
-
Credits: {mention here if you reused any code/ideas from elsewhere or if a third-party library is heavily used in the feature so that a reader can make a more accurate judgement of how much effort went into the feature}
-
-
Minor enhancement: added a history command that allows the user to navigate to previous commands using up/down keys.
-
Code contributed: [Functional code] [Test code] {give links to collated code files}
-
Other contributions:
-
Project management:
-
Managed releases
v1.3
-v1.5rc
(3 releases) on GitHub
-
-
Enhancements to existing features:
-
Documentation:
-
Did cosmetic tweaks to existing contents of the User Guide: #14
-
-
Community:
-
Tools:
-
Integrated a third party library (Natty) to the project (#42)
-
Integrated a new Github plugin (CircleCI) to the team repo
-
-
{you can add/remove categories in the list above}
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Deleting a person : delete
Deletes the specified person from the list of people.
Format: delete INDEX
Deleted items will expire in 10 seconds for testing purposes. Expired items are removed on restart of application. |
Examples:
-
list
delete 2
Deletes the 2nd person in the list of people. -
find Betsy
delete 1
Deletes the 1st person in the results of thefind
command.
Deleting a policy : deletepolicy
Deletes the specified policy from the address book.
Format: deletepolicy INDEX
Deleted items will expire in 10 seconds for testing purposes. Expired items are removed on restart of application. |
Examples:
-
listpolicy
deletepolicy 2
Deletes the 2nd policy in the list of policies. -
findpolicy senior
deletepolicy 1
Deletes the 1st policy in the results of thefindpolicy
command.
Adding policies to a person : assignpolicy
Assigns a policy to the person at the specified index.
Format: assignpolicy INDEX pol/POLICY NAME
Examples:
-
listpeople
assignpolicy 2 pol/Senior Care
Assigns the 'Senior Care' (the second policy in the list) policy to the 2nd person in the list of people. -
find Betsy
assignpolicy 1 pol/Accident Insurance
Assigns the 'Accident Insurance' (the first policy in the list) policy to the 1st person in the results of thefind
command.
Deleting policies from a person : unassignpolicy
Removes a policy from the person at the specified index.
Format: unassignpolicy INDEX pol/POLICY NAME
Examples:
-
listpeople
unassignpolicy 2 pol/Accident Insurance
Removes the policy 'Accident Insurance' in the absolute list from the 2nd person in the displayed list of people. -
find Betsy
unassignpolicy 1 pol/Health insurance
Removes the policy 'Health Insurance' in the absolute list from the 1st person in the results of thefind
command.
Deleting tags from a person : deletetag
Deletes tag(s) from the person at the specified index.
Format: deletetag INDEX t/TAG [MORE_TAGS]
Examples:
-
listpeople
deletetag 2 t/high_priority
Deletes ahigh_priority
tag from the 2nd person in the list of people. -
find Betsy
deletetag 1 t/high_risk
Deletes ahigh_risk
tag from the 1st person in the results of thefind
command.
Deleting tags from a policy : deletepolicytag
Deletes tag(s) from the policy at the specified index.
Format: deletepolicytag INDEX t/TAG [MORE_TAGS]
Examples:
-
listpolicy
deletepolicytag 2 t/high_priority
Deletes ahigh_priority
tag from the 2nd policy in the list of policies. -
findpolicy Senior
deletepolicytag 1 t/high_risk
Deletes ahigh_risk
tag from the 1st policy in the results of thefind
command.
Encrypting data files [coming in v2.0]
{explain how the user can enable/disable data encryption}
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Undo/Redo Feature
Implementation
To allow users to revert/return to a previous/future state of the address book, an undo/redo mechanism is implemented, which
undoes/redoes the last data change made in the application. This feature can be performed using the undo
or redo
command, and it performs an undo or a redo only when possible. The feature is supported by the StatefulAddressBook
class,
an instance of which is stored as one of the memory objects inside ModelManager
. The main operations implemented by this class are:
-
StatefulAddressBook#saveAddressBookState()
— Adds an address book with the current state to the liststatefulAddressBookList
. Also clears states after thecurrentStatePointer
and updates it by one. -
StatefulAddressBook#undo()
— Reverts thecurrentStatePointer
to the previous one, and resets the address book to use the one pointed bycurrentStatePointer
. -
StatefulAddressBook#redo()
— Increments thecurrentStatePointer
to the future one, and resets the address book to use the one pointed bycurrentStatePointer
.

Given below is an example usage scenario and how the undo-redo mechanism works at each step. Let us assume that StatefulAddressBook
has just been initialised.

Step 1. The user makes some data changes. This adds a list of states to our StatefulAddressBook
, and updates the
currentStatePointer
.

Step 2. User types undo
. This invokes the UndoCommand::execute
method, which further invokes the StatefulAddressBook::undo
method. The currentStatePointer
is decremented, and the address book is reset to the one being pointed to by
currentStatePointer
.

Step 3a. The use can perform another data change, following which states after currentStatePointer
are erased,
and a new state is added.

Step 3b. If a command which does not perform a data change is called, nothing happens in the StatefulAddressBook
.

Step 3c. If a redo()
is called, then the currentStatePointer
is incremented, and the address book is reset to the one
being pointed to by currentStatePointer
.

Step 4. If the address book data is reset to another state’s, then all the data inside the application is reloaded, with the resulting changes now reflected.
Following is an activity diagram which shows the execution when the user makes in a data change or types in the undo
command. The diagram for a redo
command will be similar.

Design Considerations
Aspect: How undo & redo executes
-
Alternative 1 (current choice): Saves the entire address book.
-
Pros: Easy to implement, takes way lesser code.
-
Cons: May have performance issues in terms of memory usage.
-
-
Alternative 2: Individual command knows how to undo/redo by itself.
-
Pros: Will use less memory (e.g. for delete, just save the person being deleted).
-
Cons: We must ensure that the implementation of each individual command are correct.
-
-
Alternative 3: Do not store entire address book, but a PersonList, PolicyList and BinList depending on what is changed.
-
Pros: Will use less memory (e.g. for delete, just save the person list).
-
Cons: We must ensure that the implementation of each individual command are correct. Several cases to consider when we try to undo a command.
-
Aspect: Data structure to support the undo/redo commands
-
Alternative 1 (current choice): Use a list to store the history of address book states.
-
Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project.
-
Cons: Logic is duplicated twice. For example, when a new command is executed, we must remember to update both HistoryManager and VersionedAddressBook.
-
-
Alternative 2: Use HistoryManager (a history of commands) for undo/redo
-
Pros: We do not need to maintain a separate list, and just reuse what is already in the codebase.
-
Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as HistoryManager now needs to do two different things.
-
[Proposed] Data Encryption
{Explain here how the data encryption feature will be implemented}
PROJECT: PowerPointLabs
{Optionally, you may include other projects in your portfolio.}