PROJECT: Billboard


Introduction

This portfolio is meant to document my overall contributions to the CS2103T Software Engineering Project, Billboard.

Overview

In this project, we form a team of five to develop a cross platform financial tracking application Billboard. Billboard is for those who prefer to use desktop applications to manage and keep track of their expenses. Billboard is optimized for those who prefer to work with a Command Line Interface (CLI) while still enjoying all the benefits of having a fully fledged Graphical User Interface (GUI). It is written in Java, and has about 15 kLoC.

The following is the UI of Billboard:
Billboardppp

Summary of contributions

  • Major enhancement: added the feature to undo/redo commands

    • What it does: allows you to undo all previous commands one at a time. The counter command redo can reverse the undone commands.

    • Justification: This feature improves the product significantly because it provides a convenient way for to user to rectify the mistakes made in previous commands.

    • Highlights: This enhancement affects existing and future commands. It required an in-depth analysis of design alternatives. The implementation too was challenging as it required deep copy of existing Billboard.

  • Minor enhancement:

    • added a history command that allows the user to view all the previous commands.

    • added a feature that allows the user to to navigate to previous commands using up/down keys.

  • Code contributed: [Functional code]

  • Other contributions:

    • Project setup:

      • Restructured the previous AddressBook Level-3 project to Billboard. Deleted the dead code and added attributes for Billboard. #1

    • Documentation:

      • Corrected mistakes and updated information of the project in the User Guide: #2, #3, #4, #5, #6

      • Update the image to the latest version of Billboard: #7,

    • Community:

    • Tools:

      • Applied Statistic Tool to get the statistics of the project.

Contributions to the User Guide

Given below are sections I contributed to the User Guide of Billboard, including the usage of features that I implemented such as undo/redo, history and up/down navigation, but due to the page limitation, I am only able to show the undo/redo user guide to you. It showcase my ability to write good documentation for target users.

Undo and Redo: undo/redo

  1. Undo the previous action: undo
    You can use undo command restore the previous billboard state from state history. undo will ignore the parameter you key in.
     
    Usage:

    undo

     

  2. Redo the previous undo action: redo
    You can use redo command to redo a previously undone command and restore undone billboard state from state history. redo will ignore the parameter you key in.
     
    Usage:

    redo

     

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide of Billboard, including the technical information of features that I implemented such as undo/redo, history and up/down navigation, but due to the page limitation, I am only able to show the undo/redo developer guide to you. It showcase my ability to write good technical documentation for potential developers, and the technical depth of my contributions to the project.

Undo/Redo feature

Implementation

The undo/redo mechanism is facilitated by VersionedBillboard.

If you successfully execute a command that will change the Billboard state, the current Billboard state will automatically commit to the VersionedBillboard. The current state will be store into the stateList, and a state pointer currentStatePointer will be maintained.

 List of command that will commit to VersionedBillboard:
- AddArchiveCommand
- AddCommand
- AddTagCommand
- ClearCommand
- DeleteArchiveCommand
- DeleteCommand
- RevertArchiveCommand
- EditCommand
- RemoveTagCommand

Additionally, it implements the following operations:

  • VersionedBillboard#commit() — Saves the current billboard state in its history.

  • VersionedBillboard#undo() — Restores the previous billboard state from its history.

  • VersionedBillboard#redo() — Restores a previously undone billboard state from its history.

These operations is exposed in the VersionedBillboard class as VersionedBillboard#commit()., VersionedBillboard#undo() and VersionedBillboard#redo() respectively.

Given below is an example usage scenario and how the undo/redo mechanism behaves at each step.

Step 1. The user launches the application for the first time. The VersionedBillboard will be initialized with the initial billboard state, and the currentStatePointer pointing to that single billboard state.

UndoRedoState0
Figure 1. Initial state of VersionedBillboard

Step 2. The user executes delete 5 command to delete the 5th expense in the billboard. The delete command calls VersionedBillboard#commit(), causing the modified state of the billboard after the delete 5 command executes to be saved in the stateList, and the statePointer is shifted to the newly inserted billboard state.

UndoRedoState1
Figure 2. State of VersionedBillboard after "delete 5" command

Step 3. The user executes add n/buy …​ to add a new person. The add command also calls Model#commit(), causing another modified billboard state to be saved into the stateList.

UndoRedoState2
Figure 3. State of VersionedBillboard after "add n/buy…​" command
If a command fails its execution, it will not call VersionedBillboard#commit(), so the billboard state will not be saved into the stateList.

Step 4. The user now decides that adding the expense was a mistake, and decides to undo that action by executing the undo command. The undo command will call VersionedBillboard#undo(), which will shift the currentStatePointer once to the left, pointing it to the previous billboard state, and restores the billboard to that state.

UndoRedoState3
Figure 4. State of VersionedBillboard after "undo" command
If the currentStatePointer is pointing to the initial billboard state, then there are no previous billboard states to restore. The undo command uses VersionedBillboard#isRedoable() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the undo.

The following sequence diagram shows how the undo operation works:

UndoSequenceDiagram
Figure 5. Interactions Inside the Logic Component for the undo Command
The lifeline for UndoCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.

The redo command does the opposite — it calls VersionedBillboard#redo(), which shifts the currentStatePointer once to the right, pointing to the previously undone state, and restores the billboard to that state.

If the currentStatePointer is at index stateList.size() - 1, pointing to the latest billboard state, then there are no undone billboard states to restore. The redo command uses VersionedBillboard#isRedoable() to check if this is the case. If so, it will return an error to the user rather than attempting to perform the redo.

Step 5. The user then decides to execute the command list. Commands that do not modify the billboard, such as list, will usually not call VersionedBillboard#commit(), VersionedBillboard#undo() or VersionedBillboard#redo(). Thus, the stateList remains unchanged.

UndoRedoState4
Figure 6. State of VersionedBillboard after "list" command

Step 6. The user executes clear, which calls VersionedBillboard#commit(). Since the currentStatePointer is not pointing at the end of the stateList, all billboard states after the statePointer will be purged. We designed it this way because it no longer makes sense to redo the add n/buy …​ command. This is the behavior that most modern desktop applications follow.

UndoRedoState5
Figure 7. State of VersionedBillboard after "clear" command

The following activity diagram summarizes what happens when a user executes a new command:

CommitActivityDiagram

Design Considerations

Aspect: How undo & redo executes
  • Alternative 1 (current choice): Saves the entire billboard.

    • Pros: Easy to implement.

    • 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 expense being deleted).

    • Cons: We must ensure that the implementation of each individual command are correct.

Aspect: Data structure to support the undo/redo commands
  • Alternative 1 (current choice): Use a list to store the history of billboard 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 Model and VersionedBillboard.

  • Alternative 2: Use HistoryManager 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.