SHOCO v2.1 - Developer Guide

By: Team SHOCOTech

Since: Feb 2020

Creators: Tan Kok Joon, Labi Trisha Angelica Vergara, Loh Ching Wei, Joshua, Phoon Jia Juin, Wong Jin En, Shannon

 

Table of Contents

 


1. Introduction

Purpose of this guide

This guide describes the software architecture and design of the SHOCO application. It will evolve throughout the design and implementation of each SHOCO release. Currently, this document is for the third public release of the application, SHOCO v2.1.

Scope of this guide

This document describes the software architecture and design for the implementation of SHOCO and is tailored for the developers, designers, and software testers of SHOCO.

 

🠝 back to top


2. Overview of the SHOCO application

The overview of the main classes in the application are shown in the class diagram below. Omitted are the classes for the features implemented, the LoadData class, WriteData class, FileUtil class and CommandLineTable class. alt text

The Duke class manages all required resources in the execution of the application. These include a ShoppingList object to keep track of the Item objects the user has added to his list and a Budget object to store the user’s budget.

Duke also has a Storage object for saving and loading data from the disk - this data is stored as JSON files and consists of the latest saved ShoppingList and Budget.

There is a dependency from Duke to Parser as it only creates an instance of the Parser every time user input is received by the Ui and does not keep track of the Parser which is deleted after it is done parsing the current user input. The Parser determines what command is being invoked by the user before creating a new Command object. It then returns the reference to the new Command object to Duke.

At any point in time, Duke only stores up to one Command and no more. This Command has to be executed before Duke can receive more user input.

 

🠝 back to top


3. Implementation

This section will describe how the main features of the application are implemented.

3.1 View help feature

3.1.1 Current implementation

The help feature is implemented using a HelpCommand class which extends the main Command class. The HelpCommand class shows the program usage instructions to the user.

The process is as follows:

  1. Duke receives user input from Ui.
  2. Duke calls Parser#parseCommand(). If the user input fails to match any of the correct command keywords (ADD, EDIT, DEL etc.), or if the input matches the HELP command keyword, a HelpCommand object will be instantiated.
  3. Duke calls HelpCommand#execute().
  4. HelpCommand#execute() lists all the accepted command format SHOCO recognizes, their purpose and 1 or more examples of usage.

The following sequence diagram below shows how the help feature works. Note, the Ui class is omitted in the sequence diagram to emphasise on the other classes:

Help Feature

3.1.2 Design considerations

Aspect: Data structure to support the help feature

Reason for choosing alternative 1: By abstracting out different command types as separate classes, we could work better in parallel and also be able to spot bugs more easily as each class deals with a different functionality

 

🠝 back to top


3.2 Display feature

This feature involves displaying the shopping list and budget details to the user.

3.2.1 Current implementation

The display feature is implemented using a DisplayCommand class which extends the Command class.

The process is as follows:

  1. Duke receives user input from Ui.
  2. Duke calls Parser#parseCommand() to instantiate a DisplayCommand object based on that user input.
  3. Duke then calls DisplayCommand#execute().
  4. DisplayCommand#execute() makes a call to ShoppingList#getTotalCost() to find the cost of the items.
  5. DisplayCommand#execute() then calls Budget#getAmount() and Budget#getRemainingBudget() to find the current budget and the remaining budget.
  6. The results are then printed to console.

The following sequence diagrams below show how the display feature works. Note the Ui class is omitted to emphasise the other classes:

alt text

alt text

3.2.2 Design considerations

Aspect: Data structure to support the display feature

Reason for choosing alternative 1: With each command type having its own class, we could work better in parallel and also be able to trace functionality bugs more easily if each command class deals with its own functionality.

 

🠝 back to top


3.3 Set budget feature

3.3.1 Current implementation

The set budget feature is implemented using a SetBudgetCommand class which extends the main Command class with a variable representing the budget amount.

The process is as follows:

  1. Duke receives user input from Ui.
  2. Duke calls Parser#parseCommand() to instantiate a SetBudgetCommand object based on that user input.
  3. Duke then calls SetBudgetCommand#execute().
  4. SetBudgetCommand#execute() makes another call to Budget#setBudget().
  5. The amount in the Budget object is set to the amount specified by the user.

The following sequence diagram below shows how the set budget feature works. Note the Ui class is omitted in the sequence diagram to emphasise on the other classes:

alt text

3.3.2 Design considerations

Aspect: Data structure to support the set budget feature

Reason for choosing alternative 1: By implementing each command type in a separate class, any bugs associated with a particular functionality will not affect other functionalities that significantly. It would also make it easier for us to work in parallel.

 

🠝 back to top


3.4 Add feature

3.4.1 Current implementation

The add feature is implemented using an AddCommand class. This class extends from the main Command class. The user input must contain at least a description out of these parameters: description, price, quantity. User can choose not to input price or quantity as the price will set to default which is 0.0 if the user did not input any value for price. On the other hand, quantity will set to default which is 1 if the user did not input any value for quantity.

The process is as follows:

  1. Duke class receives user input from the Ui class.
  2. A Parser object is created to call its parseCommand method.
    • The Parser object instantiates an AddCommand object based on the user input.
  3. The Duke class calls the AddCommand#execute() method of the AddCommand object.
  4. In the AddCommand#execute() method, the Item to be added is stored in the ShoppingList object, using ShoppingList#add() method.
  5. In the sequence diagram, AddCommand will add Item if the description is provided.
  6. The Item object is stored into the ShoppingList object.

The following sequence diagram below shows how the add feature works. The details of adding item’s values are shown in a separate sequence diagram below:

alt text

alt text

3.4.2 Design considerations

Aspect: Data structure to support the add feature

Reasons for choosing Alternative 1: By allowing user to just add the item without price, we can increase the flexibility. For instance, the user wants to buy milk but not sure how much does the milk cost and not sure how many milk they want to buy. So they can just add it into the list, and edit the price and quantity later when they knew the price and have decided the quantity.

 

🠝 back to top


3.5 Edit feature

3.5.1 Current implementation

The edit feature is implemented using an EditCommand class. This class extends from the main Command class. The Item object to be edited is identified by the index number provided in the user input. In addition to the index number, the user input must also contain at least one of these parameters: description, price, quantity.

The process is as follows:

  1. Duke class receives user input from the Ui class.
  2. A Parser object is created.
  3. Duke calls Parser#parseCommand() method to instantiate an EditCommand object based on the user input.
  4. Duke class calls the EditCommand#execute() method.
  5. In the EditCommand#execute() method, the Item object is retrieved through ShoppingList#getItem(). The original description / price / quantity of the item is overwritten with the new values from the user input through the use of the Item class setter methods.
  6. The Item object with its new values is stored back to the ShoppingList object.

The following sequence diagram below shows how the edit feature works. The details of updating the values of an item have been omitted from the diagram. Those details are shown in a separate sequence diagram.

Edit Feature

The separate sequence diagram below shows how an item is updated with new values.

Edit Feature SD

3.5.2 Design considerations

Aspect: Data structure to support the edit feature

Reason for choosing alternative 1: By allowing users to update any values they want, it provides them with greater convenience and freedom as they do not need to follow strict command “rules/order”. Furthermore, having greater freedom on input values makes it a hassle-free process for the users.

 

🠝 back to top


3.6 Mark and Unmark feature

3.6.1 Current Implementation

The mark and unmark feature is implemented using the MarkCommand and UnmarkCommand class which extends the main Command class with an index representing that of the item to be marked or unmarked as bought in the list.

The process is as follows:

  1. Duke first receives user input from Ui
  2. Duke creates a Parser object and calls its Parser#parseCommand() method to instantiate a MarkCommand / UnmarkCommand object based on the user input
  3. Duke then calls the MarkCommand#execute() / UnmarkCommand#execute() method.
  4. MarkCommand#execute() / UnmarkCommand#execute() makes a call to the ShoppingList#markAsBought() / ShoppingList#unmarkAsBought() method with the specified index.

The following sequence diagram below shows how the Mark feature (Diagram 1) and Unmark feature (Diagram 2) works. Note the Ui class is omitted in the sequence diagram to emphasise on the other classes:

Diagram 1:

alt text

Diagram 2:

alt text

3.6.2 Design Considerations

Aspect: Data structure to support the Mark and Unmark Feature

Reasons for choosing alternative 1: By having an individual class on it’s own, any bugs found in the mark and unmark feature can be found easier and therefore helps to resolve the issue more efficiently. Also, with the feature being implemented in an object-oriented style, reading and tracing the application code would be easier, thus making adding future features to the mark and unmark feature easier as well.

 

🠝 back to top


3.7 Find feature

3.7.1 Current implementation

The find feature is implemented using a FindCommand class which extends the main Command class with a String representing the keyword specified by the user.

The process is as follows:

  1. Duke receives user input from Ui.
  2. Duke calls Parser#parseCommand() to instantiate a FindCommand object based on that user input.
  3. Duke then calls FindCommand#execute().
  4. FindCommand#execute() makes various calls to ShoppingList#getItem() to check whether the Item at each specified index contains the given keyword.
  5. Each Item that contains the keyword is then added to a new ArrayList named filteredItems that is maintained by the FindCommand object.
  6. This list of matching results is then printed to standard output.

The following sequence diagram below shows how the Duke object creates the FindCommand object. Note the Ui class is omitted in the sequence diagram to emphasise on the other classes:

alt text

This next sequence diagram will show how the FindCommand creates the filteredItems list:

alt text

3.7.2 Design considerations

Aspect: Data structure to support the find feature

Reason for choosing alternative 1: With each command type having its own class, we could work better in parallel and also be able to trace functionality bugs more easily if each command class deals with a different functionality.

 

🠝 back to top


3.8 Delete feature

3.8.1 Current implementation

The delete feature is implemented using a DeleteCommand class which extends the main Command class with an index representing that of the item to be deleted from the shopping list.

The process is as follows:

  1. Duke receives user input from Ui.
  2. Duke calls Parser#parseCommand() to instantiate a DeleteCommand object based on that user input.
  3. Duke then calls DeleteCommand#execute().
  4. DeleteCommand#execute() makes another call to ShoppingList#deleteItem().
  5. The Item at the specified index is then removed from the ShoppingList object.

The following sequence diagram below shows how the delete feature works. Note the Ui class is omitted in the sequence diagram to emphasise on the other classes:

alt text

3.8.2 Design considerations

Aspect: Data structure to support the delete feature

Reason for choosing alternative 1: By abstracting out different command types as separate classes, this allowed us to work better in parallel and also be able to spot bugs more easily as each class deals with a different functionality.

 

🠝 back to top


3.9 Clear list feature

This feature involves clearing all items in the shopping list.

3.9.1 Current implementation

The clear list feature is implemented using a ClearCommand class which extends the Command class.

The process is as follows:

  1. Duke receives user input from Ui.
  2. Duke calls Parser#parseCommand() to instantiate a ClearCommand object based on that user input.
  3. Duke then calls ClearCommand#execute().
  4. ClearCommand#execute() makes a call to ShoppingList#clearList().

The following sequence diagram below shows how the clear list feature works. Note the Ui class is omitted to emphasise the other classes:

alt text

3.9.2 Design considerations

Aspect: Data structure to support the clear list feature

Reason for choosing alternative 1: With each command type having its own class, we could work better in parallel and also be able to trace functionality bugs more easily if each command class deals with a different functionality.

 

🠝 back to top


3.10 Reset budget feature

3.10.1 Current implementation

The reset budget feature is implemented using a ResetBudgetCommand class which extends the main Command class with a variable representing the budget amount.

The process is as follows:

  1. Duke first receives user input from the Ui class.
  2. Duke creates a Parser object and calls Parser#parseCommand() method to instantiate a ResetBudgetCommand object based on that user input.
  3. Duke then calls the ResetBudget#execute() method.
  4. ResetBudget#execute() makes a call to the Budget#resetBudget() method to set the existing budget to $0.00.

The following sequence diagram below shows how the reset budget feature works. Note the Ui class is omitted in the sequence diagram to emphasise on the other classes:

alt text

3.10.2 Design considerations

Aspect: Data structure to support the reset budget feature

Reason for choosing alternative 1: By implementing each command type in a separate class, any bugs associated with a particular functionality will not affect other functionalities that significantly. It would also make it easier for us to work in parallel.

 

🠝 back to top


3.11 Exit program feature

3.11.1 Current implementation

The program termination feature is implemented using an ExitCommand class which extends the main Command class. The ExitCommand class terminates the program when instantiated.

  1. Duke class receives user input from the Ui class.
  2. Duke calls Parser#parseCommand() to instantiate a ExitCommand object based on that user input.
  3. Duke then calls the ExitCommand#execute() method of the
  4. The program is terminated.

The following sequence diagram below shows how the exit feature works. Note the Ui class is omitted in the sequence diagram to emphasise on the other classes:

alt text

3.11.2 Design considerations

Aspect: Data structure to support the exit feature

Reason for choosing alternative 1: By abstracting out different command types as separate classes, we could work better in parallel and also be able to spot bugs more easily as each class deals with a different functionality

 

🠝 back to top


Appendix A: Product Scope

This section talks about who this product is specially designed for and what it aims to achieve.

Target user profile

Value proposition

 

🠝 back to top


Appendix B: User Stories

This section contains the user stories for the different versions of our product.

Version As a … I want to … So that I can …
v1.0 organised home cook be able to add items to the list manage the list better
v1.0 organised home cook be able to edit my budget change my budget when I need to
v1.0 organised home cook delete items from the list manage my list
v1.0 organised home cook have a useful “help” list that I can refer to find instructions for various commands
v1.0 frugal home cook add a budget so that I know how much I have to spend
v1.0 organised home cook mark things as bought keep track of my grocery progress
v1.0 frugal home cook be able to clear my budget set a new budget
v1.0 frugal home cook be able to see the total value of the items in my shopping list know that I am within budget
v1.0 frugal home cook see the remaining budget that I have left avoid exceeding my budget
v1.0 practical home cook be able to clear all items from the list with one command easily start off with a clean slate
v1.0 practical home cook see all items on my list see at a glance what I have planned to buy
v1.0 frugal home cook see my budget know if I’m within or out of my budget
v1.0 frugal home cook calculate my remaining budget see how much I have left to spend
v2.0 frugal home cook be notified when I cross my budget remove some items from my list
v2.0 practical home cook be able to search for items on my list find things easily in a long list
v2.0 practical home cook be able to edit the items in my lists keep my shopping list up to date
v2.0 organised home cook save my list have a local copy of my list
v2.0 organised home cook load my saved list add on to my existing list
v2.0 frugal home cook see the remaining budget update based on the quantity of items see how much I spend based on how much I buy

 

🠝 back to top


Appendix C: Non-Functional Requirements

  1. Should work on any OS that has Java 11 or later installed.
  2. Should respond to any user commands within 2 seconds.
  3. Should be easy to use even for people who have never used a command line interface before.

 

🠝 back to top


Appendix D: Instructions for Manual Testing

:information_source: Note: These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing.

Launch and Shutdown

  1. Initial launch

    i. Download the latest version of SHOCO, named CS2113T-T13-1.Shoco.jar under version 2.1.

    ii. Copy it into an empty folder on your desktop.

    iii. While inside the empty folder, open a command prompt window by typing CMD in the address bar of the folder.

    iv. Run the following command in the command prompt window: java -jar CS2113T-T13-1.Shoco.jar

    :bulb: Tip: If the font size of the terminal is too big, you can decrease it by CTRL + scroll down on your mouse.

     Expected: Shows a welcome message from SHOCO.
    

     

  2. Shutdown

    i. Enter the command BYE to exit the SHOCO application.

     Expected: The program is terminated.
    

     

🠝 back to top


Set and Reset a budget

  1. Set a budget

    i. Test case: SET b/500.00

    Expected: Budget is set to $500.00
    

     

    ii. Test case: SET b/10000

     Expected: Budget is set to $5000.00, which is the maximum budget SHOCO allows.
    

     

    iii. Test case: SET b/-100

     Expected: Budget is reset to $0.00, which is the minimum budget SHOCO allows.
    

     

    iv. Other incorrect set budget commands to try: SET b/xxx (where xxx is not a number).

     Expected: An error message and the correct usage of the SET command is shown.
    

     

  2. Reset the budget

    i. Test case: RES

     Expected: Budget has been reset to $0.00
    

     

    ii. Other incorrect reset budget commands to try: RES xxx (where xxx is not a number).

     Expected: An error message and the correct usage of the RES command is shown.
    

     

🠝 back to top


Add and Edit an item

  1. Add an item

    :bulb: Tip: Before adding an item, you can run the DISPLAY command to prevent entering a duplicate description

    i. Test case: ADD i/apple p/3.00 q/2

    Expected: An item with the description - "apple", price - "$3.00" and quantity - "2"  is added.
    

    :bulb: Tip: You can run the DISPLAY command to check the newly added item.

     

    ii. Test case: ADD p/3.00

     Expected: No item is added. Error message and a correct usage of the ADD command is shown.
    

     

    iii. Other incorrect ADD commands to try: ADD, ADD p/xxx, ADD q/xxx (where xxx is not a number).

     Expected: Similar to previous. 
    

     

  2. Edit an item

    :bulb: Tip: You can run the DISPLAY command to check if the item has been correctly updated.

    Assumption: Valid index and description is provided. (No duplicate description allowed)

    i. Test case: EDIT 1 i/banana

     Expected: The description of the first item is updated to "banana". 
    

     

    ii. Test case: EDIT 1 p/5.60

     Expected: The price of the first item is updated to "$5.60". 
    

     

    iii. Test case: EDIT 1 q/3

     Expected: The quantity of the first item is updated to "3". 
    

     

    iv. Other incorrect edit commands to try: EDIT p/xxx , EDIT q/xxx. (where xxx is not a number).

     Expected: An error message and the correct usage of the EDIT command is shown.
    

     

🠝 back to top


Mark and Un-mark an item

  1. Marking an item

    Assumption: there are more than 5 but less than a hundred items in the list.

    i. Test case: MARK 5

     Expected: The fifth item in the list is mark as bought, denoted as [B].
    

     

    ii. Test case: MARK -10

     Expected: An error message stating that the item does not exist in the list is shown.
    

     

    iii. Test case: MARK 100

     Expected: An error message stating that the item does not exist in the list is shown.
    

     

    iv. Other incorrect MARK commands to try: MARK xxx (where xxx is not a number).

      Expected: An error message stating to provide a single numerical index number is shown.
    

     

  2. Un-marking an item

    Assumption: there are more than 5 and less than a hundred items in the list.

    i. Test case: UNMARK 5

      Expected: The fifth item in the list is marked as not bought yet, denoted as [X].
    

     

    ii. Test case: UNMARK -10

    Expected: An error message stating that the item does not exist in the list is shown.
    

     

    iii. Test case: UNMARK 100

    Expected: An error message stating that the item does not exist in the list is shown.
    

     

    iv. Other incorrect UNMARK commands to try: UNMARK xxx (where xxx is not a number).

     Expected: An error message stating to provide a single numerical index number is shown.
    

     

🠝 back to top


Find and Delete an item

  1. Find an item based on keyword

    i. Test case: FIND apple

    Expected: A list of items that contains "apple" in their description is displayed.
    

     

    ii. Test case: FIND xxx (where xxx is a keyword that is unmatched)

     Expected: An error message and the correct usage of the FIND command is shown.
    

     

  2. Delete an item

    :bulb: Tip: You can run the DISPLAY command to check the index of an item.

    i. Test case: DEL 1

    Expected: The first item (if it exists), is deleted.
    

     

    ii. Test case: DEL xxx (where xxx is a not a number / the item does not exist yet)

     Expected: An error message and the correct usage of the DEL command is shown.
    

     

🠝 back to top


Display and Clear the shopping list

  1. List all items in the shopping list

    i. Test case: DISPLAY

     Expected: A list of all the items and the current budget amount is displayed.
    

     

  2. Clear all items in the shopping list

    i. Test case: CLEAR

     Expected: The shopping list is cleared.
    

     

🠝 back to top