By: AY1920S1-CS2103T-W11-3
Since: Sep 2019
Licence: MIT
Refer to the guide here.
The Architecture Diagram given above explains the high-level design of the App. Given below is a quick overview of each component.
💡
|
The .puml files used to create diagrams in this document can be found in the diagrams folder.
Refer to the Using PlantUML guide to learn how to create and edit diagrams.
|
-
At app launch: Initializes the components in the correct sequence, and connects them up with each other.
-
At shut down: Shuts down the components and invokes cleanup method where necessary.
Commons
represents a collection of classes used by multiple other components.
The following class plays an important role at the architecture level:
-
LogsCenter
: Used by many classes to write log messages to the App’s log file.
The rest of the App consists of four components.
Each of the four components
-
Defines its API in an
interface
with the same name as the Component. -
Exposes its functionality using a
{Component Name}Manager
class.
For example, the Logic
component (see the class diagram given below) defines it’s API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1
.
The sections below give more details of each component.
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, EateryListPanel
, StatusBarFooter
etc. All these, including the MainWindow
, inherit from the abstract UiPart
class.
The UI
component uses JavaFx UI framework. The layout of these UI parts are defined in matching .fxml
files that are in the src/main/resources/view
folder. For example, the layout of the MainWindow
is specified in MainWindow.fxml
The UI
component,
-
Executes user commands using the
Logic
component. -
Listens for changes to
Model
data so that the UI can be updated with the modified data.
API :
Logic.java
-
Logic
uses theAddressBookParser
class to parse the user command. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding anEatery
). -
The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
. -
In addition, the
CommandResult
object can also instruct theUi
to perform certain actions, such as displaying help to the user.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete 1")
API call.
ℹ️
|
The lifeline for DeleteCommandParser should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the Address Book data.
-
exposes an unmodifiable
ObservableList<Eatery>
that can be 'observed' e.g. the UI can be bound to this list so that the UI automatically updates when the data in the list change. -
does not depend on any of the other three components.
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the Address Book data in json format and read it back.
This section describes some noteworthy details on how certain features are implemented.
The add mechanism is facilitated by AddressBook
. It implements the following operations:
-
AddressBook#hasEatery()
— Checks if an Eatery with the same identity as Eatery e exists in the address book. -
AddressBook#addEatery()
— Adds an Eatery to the address book. The eatery must not already exist in the address book.
These operations are exposed in the Model
interface as Model#hasEatery()
and Model#addEatery()
respectively.
Given below is an example usage scenario and how the add mechanism behaves at each step.
Step 1. The user launches the application for the first time. The AddressBook
will be initialized with the initial json data stored.
Step 2. The user executes add \n Two Chefs Eating Place \a 116 Commonwealth Cres, #01-129 \c Chinese
to add a new eatery. The add
command will call Model#addEatery()
.
ℹ️
|
If the command is missing a Name , Address , or Category parameter, it will return an error to the user rather than attempting to add the Eatery.
|
The following activity diagram summarizes what happens when a user executes a new command: image::add-ad.PNG[]
-
Alternative 1 (current choice): Making Tag field not final.
-
Pros:
-
Easily implemented.
-
More user-friendly as users would most likely want to delete or add new tags.
-
-
Cons: Does not follow the logic of the original Address Book 3 application. More code needs to be refactored.
-
-
Alternative 2: Making Tag field final.
-
Pros: Follows the logic of the original Address Book 3 application; don’t need to refactor more code.
-
Cons: Not as user-friendly.
-
The review mechanism is facilitated by the existing AddressBook
.
It extends AddressBook
with a review field, stored internally as an array list of reviews along with other
attributes of an eatery.
Additionally, it implements the following operations:
-
AddressBook#review()
— Adds a review to the eatery identified by the user input. -
AddressBook#editReview()
— Edits a previously written review.
Given below is an example usage scenario and how the review mechanism behaves at each step.
Step 1. The user launches the application for the first time. The AddressBook
will be initialized with the initial json data stored.
Step 2. The user executes review 1 …
command to add a review to the first Eatery in the address book. The review
command will call Eatery#addReview()
.
ℹ️
|
If the index given is not a valid index (ie, out of bounds or negative), it will return an error to the user rather than attempting to review the Eatery. |
Step 3. The user executes open 1
to get the complete details of the first Eatery.
Step 4. The user then decides to execute edit review 1 …
to edit the first review of the Eatery opened in the previous step. This calls the EatMe#editcommand()
.
-
Alternative 1 (current choice): No further nesting of Review field in Eatery.
-
Pros: Easily implemented.
-
Cons: May be worse OOP model as compared to other commands.
-
-
Alternative 2: Further nesting of Review field in Eatery.
-
Pros: A better OOP model.
-
Cons: May decrease performance and difficult to implement.
-
-
Current choice: Store and edit the reviews of an eatery in a list.
-
Pros: Easy for new Computer Science student undergraduates to understand, who are likely to be the new incoming developers of our project.
-
Cons: List is not immutable.
-
The close mechanism is facilitated by AddressBook
. It implements ReadOnlyAddressBook interface with the following operation:
-
AddressBook#setEatery()
— Replaces an Eatery with a modified Eatery specified by the user input.
Given below is an example usage scenario and how the close mechanism behaves at each step.
Step 1. The user launches the application for the first time. The AddressBook
will be initialized with the initial json data stored.
Step 2. The user executes close 1
command to close the 1st Eatery in the address book.
ℹ️
|
If the index given is not a valid index (ie, out of bounds or negative), it will return an error to the user rather than attempting to close the Eatery. |
Step 3. The address book now returns a success message upon successfully closing the Eatery, and the Eatery will be greyed out [proposed].
Step 4. The user then decides that he wants to close another Eatery.
ℹ️
|
If the index given points to an Eatery already closed (ie, 1 in this situation), it will return an error to the user rather than attempting to close the Eatery. |
The following sequence diagram shows how the close
command works:
image::CloseSequenceDiagram.png[]
The following activity diagram summarizes what happens when a user executes a new close
command:
image::CloseCommitActivityDiagram.png[]
-
Alternative 1 (current choice): Returns a new Eatery with identical fields except for the isOpen field.
-
Pros:
-
Follows pre-exisiting EditCommand implementation.
-
No need for setter methods.
-
-
Cons: Have to return a new object each time a change is made.
-
-
Alternative 2: Setter method for isOpen field of Eatery.
-
Pros: No need for extra methods in the flow to change the object.
-
Cons:
-
Breaks pre-existing EditCommand implementation.
-
Need for setter methods.
-
-
-
Alternative 1 (current choice): Uses a boolean value to keep track if the Eatery is reopened or closed.
-
Pros: Easily implemented.
-
Cons: An additional variable to check when executing other commands. Possibility of incorrect manipulation of an Eatery object
-
-
Alternative 2: Maintain two separate lists of Eateries for Reopened and Closed.
-
Pros: Closed Eateries stored apart from Reopened Eateries. Commands executed will only affect Eateries stored in a particular list.
-
Cons: Requires proper handling of individual data structures to ensure each list is maintained and updated correctly.
-
Allows the user to toggle between Main mode and Todo mode. It extends Command
, and once the mode has been switched, it will affect all other command functions.
The mode is determined through the isMainMode
boolean variable.
Given below is an example usage scenario and how the mode mechanism behaves at each step.
Step 1: The user launches the application. The AddressBook
will be will be initialised as the Main Mode with the initial json data stored.
Step 2: The user executes mode
command to switch EatMe to the Todo Mode which displays Eateries
in the Todo list.
Step 3: The user can execute mode
command again to switch EatMe back to the Main Mode which displays the Eateries
in the Main list.
The following sequence diagram shows how the mode
command works:
image::ModeCommandSequenceDiagram.png[]
The following activity diagram summarizes what happens when a user executes a new mode
command:
image::ModeCommandActivity.png[]
-
Current choice: Toggles between mode through a boolean value.
-
Pros: Easily implemented.
-
Cons: An additional variable to check when executing other commands. Possibility of incorrect manipulation of an Eatery object.
-
-
Current choice: Maintains two separate lists of Eateries for Main mode and Todo Mode.
-
Pros: Todo Eateries stored apart from Main Eateries. Commands executed will only affect Eateries stored in a particular list.
-
Cons: Requires proper handling of individual data structures to ensure each list is maintained and updated correctly.
-
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels and logging destinations.
-
The logging level can be controlled using the
logLevel
setting in the configuration file (See Section 3.6, “Configuration”) -
The
Logger
for a class can be obtained usingLogsCenter.getLogger(Class)
which will log messages according to the specified logging level -
Currently log messages are output through:
Console
and to a.log
file.
Logging Levels
-
SEVERE
: Critical problem detected which may possibly cause the termination of the application -
WARNING
: Can continue, but with caution -
INFO
: Information showing the noteworthy actions by EatMe -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
Refer to the guide here.
Refer to the guide here.
Refer to the guide here.
Target user profile:
Value proposition: manage eateries faster than a typical mouse/GUI driven app with statistics of key details such as budget, category and location
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
food blogger |
keep a list of outstanding cafes |
clear them in an orderly fashion. |
|
student |
keep a list of affordable eateries |
save money |
|
person with many food allergies |
keep track of dishes I have ordered before |
avoid ordering hazardous food |
|
foodie |
remember places |
share this experience with my family and friends |
|
digital nomad |
tag places with free power + wifi |
sit there for extended periods of time |
|
working adult |
view the menu beforehand |
save time from thinking what to eat |
{More to be added}
(For all use cases below, the System is the EatMe
and the Actor is the user
, unless specified otherwise)
MSS
-
User requests to view his todo list
-
EatMe toggles to the todo mode
-
User requests to mark an eatery as visited in the list
-
EatMe shifts the data over
-
EatMe toggles to the main mode
-
EatMe requests user for whatever information left that is required before saving in the main mode
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given eatery is invalid.
-
3a1. EatMe shows an error message.
Use case resumes at step 2.
-
-
6a. The given information is of the wrong format.
-
6a1. EatMe shows an error message.
Use case resumes at step 8.
-
MSS
-
User requests to add a tag to an eatery
-
EatMe updates the eatery accordingly
Use case ends.
Extensions
-
1a. The list is empty.
Use case ends.
-
1b. The user gives invalid information.
-
1b1. EatMe shows an error message.
Use case resumes at step 1.
-
MSS
-
User searches for an eatery
-
EatMe displays the eatery accordingly
-
User reads the entry for the menu
Use case ends.
Extensions
-
1a. The list is empty.
Use case ends.
-
1b. The user gives invalid information.
-
1b1. EatMe shows an error message.
Use case resumes at step 1.
-
{More to be added}
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
Should be able to hold up to 1000 eateries without a noticeable sluggishness in performance for typical usage.
-
A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse.
-
Main functionalities (CRUD) should work without WiFi.
{More to be added}
Soon
Author: Beginner AB
Pros:
-
Shows trending restaurants nearby
-
Hide option
Cons:
-
Unable to delete lists
-
Unable to search
Given below are instructions to test the app manually.
ℹ️
|
These instructions only provide a starting point for testers to work on; testers are expected to do more exploratory testing. |
-
Initial launch
-
Download the jar file and copy into an empty folder.
-
Double-click the jar file
Expected: Shows the GUI with a set of sample contacts. The window size may not be optimum.
-
-
Saving window preferences
-
Resize the window to an optimum size. Move the window to a different location. Close the window.
-
Re-launch the app by double-clicking the jar file.
Expected: The most recent window size and location is retained.
-
{ more test cases … }
-
Deleting an
Eatery
while allEateries
are listed-
Prerequisites: List all
Eateries
using the list command. MultipleEateries
in the list. -
Test case:
delete 1
Expected: FirstEatery
is deleted from the list. Details of the deletedEatery
shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete 0
Expected: NoEatery
is deleted. Error details shown in the status message. Status bar remains the same. -
Other incorrect delete commands to try:
delete
,delete x
(where x is larger than the list size, or x is a non-integer)
Expected: Similar to previous.
-
{ more test cases to be added }
-
[Proposed] Dealing with missing/corrupted data files
-
Prerequisites: json file type present in a data file where the EatMe app is.
-
Test case: Running the application with json file type with incorrect format
Expected: Application starts with a blankEatery
list panel. Error details shown in the status message.
-
{ more test cases to be added }