PROJECT: AddressBook - Level 3


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:

      • Updated the GUI color scheme (Pull requests #33, #34)

      • Wrote additional tests for existing features to increase coverage from 88% to 92% (Pull requests #36, #38)

    • Documentation:

      • Did cosmetic tweaks to existing contents of the User Guide: #14

    • Community:

      • PRs reviewed (with non-trivial review comments): #12, #32, #19, #42

      • Contributed to forum discussions (examples: 1, 2, 3, 4)

      • Reported bugs and suggestions for other teams in the class (examples: 1, 2, 3)

      • Some parts of the history feature I added was adopted by several other class mates (1, 2)

    • 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

  • Deletes the person at the specified INDEX.

  • The index refers to the index number shown in the displayed person list.

  • The index must be a positive integer 1, 2, 3, …​

  • Deleted persons are moved into the bin, where they stay there for a default of 30 days before being removed permanently. This default value can be changed with the binitemexpiry command.

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 the find command.

Deleting a policy : deletepolicy

Deletes the specified policy from the address book.
Format: deletepolicy INDEX

  • Deletes the policy at the specified INDEX.

  • The index refers to the index number shown in the displayed policy list.

  • The index must be a positive integer 1, 2, 3, …​

  • Deleted persons are moved into the bin, where they stay there for a default of 30 days before being removed permanently. This default value can be changed with the binitemexpiry command.

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 the findpolicy command.

Adding policies to a person : assignpolicy

Assigns a policy to the person at the specified index.
Format: assignpolicy INDEX pol/POLICY NAME

  • The index refers to the index number shown in the displayed person list. The index must be a positive integer 1, 2, 3, …​

  • The policy name refers to the name of the policy.

  • A policy already assigned cannot be assigned again.

  • Each policy name must match the policy exactly as it appears in the absolute policy list.

  • Any number of policies can be added as long as the person is eligible for the policy.

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 the find command.

Deleting policies from a person : unassignpolicy

Removes a policy from the person at the specified index.
Format: unassignpolicy INDEX pol/POLICY NAME

  • The index refers to the index number shown in the displayed person list. The index must be a positive integer 1, 2, 3, …​

  • The policy name refers to the name of the policy.

  • A policy already unassigned cannot be unassigned again.

  • Each policy name must match the policy exactly as it appears in the absolute policy list.

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 the find command.

Deleting tags from a person : deletetag

Deletes tag(s) from the person at the specified index.
Format: deletetag INDEX t/TAG [MORE_TAGS]

  • Deletes the tags from the person at the specified INDEX.

  • The index refers to the index number shown in the displayed person list.

  • The index must be a positive integer 1, 2, 3, …​

  • Any number of tags can be deleted.

Examples:

  • listpeople
    deletetag 2 t/high_priority
    Deletes a high_priority tag from the 2nd person in the list of people.

  • find Betsy
    deletetag 1 t/high_risk
    Deletes a high_risk tag from the 1st person in the results of the find command.

Deleting tags from a policy : deletepolicytag

Deletes tag(s) from the policy at the specified index.
Format: deletepolicytag INDEX t/TAG [MORE_TAGS]

  • Deletes the tags from the policy at the specified INDEX.

  • The index refers to the index number shown in the displayed policies list.

  • The index must be a positive integer 1, 2, 3, …​

  • Any number of tags can be deleted.

Examples:

  • listpolicy
    deletepolicytag 2 t/high_priority
    Deletes a high_priority tag from the 2nd policy in the list of policies.

  • findpolicy Senior
    deletepolicytag 1 t/high_risk
    Deletes a high_risk tag from the 1st policy in the results of the find 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 list statefulAddressBookList. Also clears states after the currentStatePointer and updates it by one.

  • StatefulAddressBook#undo() — Reverts the currentStatePointer to the previous one, and resets the address book to use the one pointed by currentStatePointer.

  • StatefulAddressBook#redo() — Increments the currentStatePointer to the future one, and resets the address book to use the one pointed by currentStatePointer.

UndoRedoClassDiagram

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.

UndoRedoState0

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

UndoRedoState1

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.

UndoRedoState2

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

UndoRedoState3a

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

UndoRedoState3b

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.

UndoRedoState3c

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.

UndoActivityDiagram

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.}