Developer Guide
- 1. How to navigate this Developer Guide
- 2. Setting up, getting started
- 3. Design
- 4. Implementation
- 5. Documentation, logging, testing, configuration, dev-ops
- 6. Appendix: Requirements
- 7. Appendix: Instructions for manual testing
1. How to navigate this Developer Guide
The target audience of this guide is for anyone who wishes to extend or modify the functionality of ZooKeepBook. The guide is split into 3 sections, covering the design of ZooKeepBook, the implementation of certain features as well as how to manage the development of ZooKeepBook.
The following symbols are used throughout this developer guide. They highlight important information that may be useful to you:
Symbol | Description |
---|---|
This block contains additional tips that may aid you | |
This block contains additional information that may be used to elaborate on the content presented | |
text markup |
Indicates Java class and method names |
2. Setting up, getting started
Refer to the guide Setting up and getting started.
3. Design
This section describes the high-level components that make up ZooKeep.
3.1. Architecture
The Architecture Diagram (Figure 1) given below explains the high-level design of the App.
Figure 1: The Architecture Diagram of ZooKeep
Given below is a quick overview of each component.
.puml
files used to create diagrams in this document can be found in the
diagrams folder. Refer
to the PlantUML Tutorial at se-edu/guides
to learn how to create and edit diagrams.
Main
has two classes called Main
and MainApp
.
It is responsible for the following situations:
- 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 methods where necessary.
Commons
represents a collection of classes used by multiple other components.
The rest of the App consists of four components:
-
UI
: The UI of the App. -
Logic
: The command executor. -
Model
: Holds the data of the App in memory. -
Storage
: Reads data from and writes data to the hard disk.
Each of the four components
- defines its API in an
interface
with the same name as the Component. - exposes its functionality using a concrete
{Component Name}Manager
class (which implements the corresponding APIinterface
mentioned in the previous point.
For example, the Logic
component (see Figure 2 below) defines its API
in the Logic.java
interface and exposes its functionality using the LogicManager.java
class
which implements the Logic
interface.
Figure 2: Class Diagram of Logic component
The Sequence Diagram (Figure 3) below shows how the components interact with each other for the
scenario where the user issues the command delete 123
.
Figure 3: Sequence Diagram of delete command
The sections below give more details of each component.
3.2. UI component
The Class Diagram for the UI Component is shown below (Figure 4)
Figure 4: Class Diagram of UI Component
API :
Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, AnimalListPanel
, 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.
3.3. Logic component
The Class Diagram for the Logic Component is shown below (Figure 5)
Figure 5: Class Diagram of Logic Component
API :
Logic.java
-
Logic
uses theZooKeepBookParser
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 an animal). - 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 (Figure 6) for interactions within the Logic
component for the execute("delete 1")
API call.
Figure 6: Sequence Diagram for delete command
DeleteCommandParser
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
3.4. Model component
The Class Diagram for the Model Component is shown below (Figure 7)
Figure 7: Class Diagram of Model Component
API : Model.java
The Model
,
- stores a
UserPref
object that represents the user’s preferences. - stores the ZooKeepBook data.
- exposes an unmodifiable
ObservableList<Animal>
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.
MedicalCondition
and FeedTime
lists in the ZooKeepBook
, which Animal
references. This allows ZooKeepBook
to only require one MedicalCondition
or FeedTime
object per unique MedicalCondition
or FeedTime
, instead of each Animal
needing their own MedicalCondition
or FeedTime
objects.3.5. Storage component
The Class Diagram for the Storage Component is shown below (Figure 8)
Figure 8: Class Diagram of Storage Component
API : Storage.java
The Storage
component,
- can save
UserPref
objects in json format and read it back. - can save the ZooKeepBook data in json format and read it back.
3.6. Common classes
Classes used by multiple components are in the seedu.zookeepbook.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1. Undo feature (by Zhi Yuan)
4.1.1. Implementation
The undo feature is facilitated by a stack data structure.
The HistoryStack
class wraps a stack designed to hold ReadOnlyZooKeepBook
objects.
The Singleton Pattern is employed here since only one history instance should exist in the running of the application.
HistoryStack
supports the following key features:
-
HistoryStack#addToHistory(ReadOnlyZooKeepBook)
- Adds the given state of the book into history only if it differs from the most recent state. -
HistoryStack#removeRecentHistory()
- Removes the most recent state of the book from the history. -
HistoryStack#viewRecentHistory()
- Returns the most recent state of the book. -
HistoryStack#clearHistory()
- Clears the history.
The undo feature also depends on the following existing methods:
-
Model#setZooKeepBook(ReadOnlyZooKeepBook)
- Replaces the current model’s book data with the given. -
Model#getZooKeepBook()
- Returns the model’s current book.
The following classes reference the above methods:
UndoCommand
LogicManager
Given below is an example usage scenario and how the undo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The HistoryStack
will be initialized with a single state (Figure 9), which is the current state.
Figure 9: State of HistoryStack upon initialization
Step 2. The user executes delete 1
command to delete the animal with ID 1. LogicManager
calls Model#getZooKeepBook()
to retrieve the new state of the book, and adds it to the history (Figure 10) with HistoryStack#addToHistory(ReadOnlyZooKeepBook)
.
Figure 10: State of HistoryStack after addition of new state
Step 3. The user executes help
to view the help screen. LogicManager
behaves as per Step 2. However, since no changes were made to the state, the current state is not added (Figure 11) to HistoryStack
.
Figure 11: State of HistoryStack unchanged
HistoryStack#addToHistory()
, so the state will not be saved into the HistoryStack
.
Step 4. The user now decides that deleting the person was a mistake, and decides to undo that action by executing the undo
command. The undo
command will call HistoryStack#removeRecentHistory()
which deletes the current state, and exposes the previous state. HistoryStack#viewRecentHistory()
is then called to retrieve the previous state, then loaded into the model (Figure 12) using Model#setZooKeepBook(ReadOnlyZooKeepBook)
.
Figure 12: State of HistoryStack after loading the previous state
HistoryStack
only contains a single state, then there is no previous state to restore. The undo
command uses HistoryStack#getHistorySize()
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 (Figure 13) shows how the undo operation works:
Figure 13: Sequence Diagram when undo command is executed
UndoCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following 2 Activity Diagrams (Figures 14.1 & 14.2) summarize what happens when a user executes a new command and when a user executes the undo command:
Figure 14.1 (left): Activity Diagram when user executes a command
Figure 14.2 (right): Activity Diagram when user undoes a command
4.1.2. Design consideration:
4.1.2.1. Aspect: How undo executes
-
Alternative 1 (current choice): Saves the entire ZooKeepBook as a state.
- Pros: Easy to implement, works with all commands immediately.
- Cons: May have performance issues in terms of memory usage as product scales.
-
Alternative 2: Individual command knows how to undo by
itself.
- Pros: Will use less memory (e.g. for
delete
, just save the animal being deleted). - Cons: We must ensure that the implementation of each individual command are correct.
- Pros: Will use less memory (e.g. for
4.2. Redo feature (by Jun Cheng)
4.2.1. Implementation
The Redo feature was added as a complement to the Undo feature which was done earlier. The addition of this
feature required the integration of the RedoCommand
class, which extends from the Command
class like all other commands.
The HistoryStack
class also has new key features to support the redo
command:
-
HistoryStack#addToRedo(ReadOnlyZooKeepBook)
- Adds a given state of the ZooKeepBook into the redo stack. -
HistoryStack#removeRecentRedo()
- Removes the most ‘recent’ update of the ZooKeepBook from the redo stack. -
HistoryStack#viewRecentRedo()
- Returns (but does not remove) the most ‘recent’ update of the ZooKeepBook. -
HistoryStack#clearRedo()
- Clears the future updates of the ZooKeepBook stored in the redo stack.
The RedoCommand
class references some of these methods to accomplish the feature required. Given below is an example
usage scenario and how the redo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The ZooKeepBook is initialised with the initial state
given in data/zookeepbook.json
, and the HistoryStack
consists of 2 stacks; the history stack and the redo stack,
each in their respective initial states (Figure 15).
Figure 15: State of both stacks during initialization
Step 2. The user executes add n/Harambe...
to add a new animal into the ZooKeepBook. The LogicManager
calls
Model#getZooKeepBook()
to retrieve the new state of the book and calls HistoryStack#addToHistory(ReadOnlyZooKeepBook)
as per normal undo protocol (Figure 16).
Figure 16: State of both stacks after executing add command
Step 3. The user then executes delete 567
which deletes the animal in the book with an ID of 567. Similar to step 2,
LogicManager
will call Model#getZooKeepBook()
to retrieve the new state of the book and then calls
HistoryStack#addToHistory(ReadOnlyZooKeepBook)
to store this state into the history stack (Figure 17).
Figure 17: State of both stacks after executing delete command
Step 4. Now the user thinks that deleting that animal was a mistake and restores the previous state by
executing undo
(explained in the previous section). However, before the current state is deleted and replaced with
the previous one, HistoryStack#addToRedo(ReadOnlyZooKeepBook)
is called to store the current state into the redo
stack (Figure 18) for further use.
Figure 18: State of both stacks after executing undo command
UndoCommand
is never executed, the
redo stack will remain empty and calling RedoCommand
will do nothing, since there are no future states recorded in
the stack for retrieval.
Step 5. However, now the user decides that deleting that animal was the correct decision after all, and now executes
redo
which calls HistoryStack#viewRecentRedo()
to retrieve the future state of the ZooKeepBook where the animal
was deleted. The future state is then loaded into the model using Model#setZooKeepBook(ReadOnlyZooKeepBook)
.
Lastly, HistoryStack#removeRecentRedo()
is called to delete that state from redo stack (Figure 19).
Figure 19: State of both stacks after executing redo command
The following Sequence Diagram (Figure 20) illustrates how the Redo
operation is performed:
Figure 20: Sequence Diagram when redo command is executed
RedoCommand
should end
at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following 2 Activity Diagrams (Figures 21.1 & 21.2) summarise what happens when a user executes the undo
and redo
commands:
Figure 21.1 (left): Activity Diagram when user executes an undo command
Figure 21.2 (right): Activity Diagram when user executes a redo command
4.2.2. Design consideration:
4.2.2.1. Aspect: How redo executes
-
Alternative 1 (current choice): Saves the entire ZooKeepBook as a state.
- Pros: Easy to implement, works with all commands immediately.
- Cons: May have performance issues in terms of memory usage as product scales.
-
Alternative 2: Individual command knows how to redo by
itself.
- Pros: Will use less memory (e.g. for
delete
, just save the animal being deleted). - Cons: We must ensure that the implementation of each individual command are correct.
- Pros: Will use less memory (e.g. for
4.3. Snapshot feature (by Aizat)
4.3.1. Implementation
This section explains the implementation of the snapshot feature. This feature allows users
to save the current state of their ZooKeepBook
as a json file with their desired file name.
The snapshot feature is implemented by the SnapCommand
and SnapCommandParser
classes.
SnapCommandParser
parses the user’s input as a file name. If the file name is valid,
it returns a SnapCommand
object with a Path
object representing the save destination
and the file name as arguments. If the file name is invalid, it returns an error message.
SnapCommand
executes by copying the current state of the ZooKeepBook
and then calls
StorageManager#saveZooKeepBook(...)
to save the copied ZooKeepBook
with the user specified file name.
The following Sequence Diagram (Figure 22) illustrates the creation and execution of a SnapCommand
:
Figure 22: Sequence Diagram when snap command is executed
SnapCommandParser
, SnapCommand
, StorageManager
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
The following Activity Diagram (Figure 23) shows the flow of the execution of a SnapCommand
:
Figure 23: Activity Diagram when snap command is executed
4.3.2. Design consideration:
4.3.2.1. Aspect: Overwriting files
- We chose to prevent users from creating a snapshot if the specified file name already exists as overwriting a file is irreversible and would be disastrous for zookeepers if done unintentionally
4.4. Sort feature (by Malcolm)
4.4.1. Implementation
This section explains the implementation of the Sort command feature in the ZooKeepBook. This feature is used to sort the animals based on the different categories: name, id, feedtime or medical.
- For the animal name, it will be in alphabetical order.
- For the animal id, it will be in ascending order.
- For the animal feed time, it will be the earliest feed time in chronological order.
- For the animal medical condition, it will be the number of conditions in ascending order.
The following Sequence Diagram (Figure 24) shows the Logic and Model Components when a sort command is being executed:
Figure 24: Sequence Diagram when sort command is executed
SortCommand
should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
In the Logic Component,
After the user keys in “sort name” as input, these key methods are called:
-
LogicManager#execute("sort name")
: TheLogicManager
takes in a command text string (“sort name/id/feedtime/medical”). -
ZooKeepBookParser#parseCommand("sort name")
: TheZooKeepBookParser
parses the user input into a command word (“sort”) and arguments (“name”). Using the command word, aSortCommandParser
is created. -
SortCommandParser#parse("name")
: TheSortCommandParser
takes in the argument(“name”) and parses it. AnAnimalComparator
is created and contains the specific static comparator required to sort the animals according to the category provided. ASortCommand
is created with theAnimalComparator
as an attribute.- The
AnimalComparator
contains 4 different static comparators to be used for sorting:ANIMAL_NAME_COMPARATOR
,ANIMAL_ID_COMPARATOR
,ANIMAL_FEEDTIME_COMPARATOR
andANIMAL_MEDICAL_COMPARATOR
. - In this case, the
ANIMAL_NAME_COMPARATOR
is taken.
- The
-
SortCommand#execute(model)
: TheSortCommand
uses theAnimalComparator
to sort the animals and returns aCommandResult
object which represents the result of a command execution.
In the Model Component,
The in-memory model of the ZooKeepBook data sorts and updates the animal list. The following key methods are used:
-
Model#sortAnimals(animalComparator)
: sorts the animals in theZooKeepBook
using the givenAnimalComparator
object. -
ZooKeepBook#sortAnimals(animalComparator)
: Retrieves the static comparator in theAnimalComparator
object and creates aSortedList
object. TheUniqueAnimalList
in theZooKeepBook
is then replaced by thisSortedList
object. -
ZooKeepBook#updateFilteredAnimalList(predicate)
: Updates the filter of the filtered animal list to filter by the given predicate, which will be true here so that the sorted list will be displayed once sorted.
Upon the completion of the user command, a success message (Sorted all animals by name) and the updated sorted list is displayed below the message.
The following Activity Diagram (Figure 25) summarises what happens when a user executes a sort command.
Figure 25: Activity Diagram when user executes sort command
4.4.2. Design Consideration:
4.4.2.1. Aspect: Sorting based on different categories
We chose to allow the user to sort not only based on animal names but also by their id, earliest feed times or number of medical conditions to ease the convenience of the user when he needs data to be sorted in other ways.
4.5. Feed times feature (by Jeremy)
4.5.1. Implementation
The feed times feature utilizes a TreeSet with a custom comparator.
Each Animal object has a FeedTimes
TreeSet.
The custom comparator FeedTimeComparator
compares the integer values of the feed times, returning them in ascending order.
The feed times feature allows for the following functionality:
- Add multiple feed times to each animal listing.
- Ensure feed times are always displayed in chronological order.
The following notable methods are used for the feed times feature:
-
ParserUtil#parseFeedTimes(Collection<String>)
- returns a Set ofFeedTime
objects from user input -
FeedTime#isValidFeedTime(String)
- validates the feed time to ensure it is in the HHmm format
The parsing and displaying of feed times were adapted from the Medical Condition field.
Given below is a Sequence Diagram (Figure 26) shows how the operation of adding feed times works.
Figure 26: Sequence Diagram when animal is added with feed times
Step 1. The user inputs an add command, specifying feed times to be added for an Animal (eg. add n/Pikachu i/1307 s/Pokemon f/1234 f/0001 f/2200)
Step 2. The ZooKeepBook
class receives the user input. AddCommand.COMMAND_WORD
is used to identify the type of command.
Step 3. The AddCommandParser
class receives the arguments in the user input. The ArgumentTokenizer
class is called with the PREFIX_FEED_TIME
variable.
Step 4. The ArgumentTokenizer
class returns the feed times found in the users input. A set of FeedTime
objects is created by the parseFeedTimes
method in the ParserUtil
class.
Step 5. An Animal
object is created with the Set of FeedTime
objects.
The following Activity Diagram (Figure 27) summarizes what happens when feed times are added to an Animal:
Figure 27: Activity Diagram when user adds an animal with feed times
4.5.2. Design consideration:
4.5.2.1. Aspect: How chronological order is maintained
-
Alternative 1 (current choice): Store the feed times in chronological order
- Pros: Quick to display when retrieving information
- Cons: Initial creation and storage of feed times takes longer
-
Alternative 2: Sort the feed times when information is retrieved
itself.
- Pros: Quick during the initial creation of Animal objects
- Cons: Additional processing time required when displaying each Animal object
5. Documentation, logging, testing, configuration, dev-ops
This section provides guides for developers wishing to take on this framework for extension or morphing.
6. Appendix: Requirements
This section lists the target requirements for ZooKeep.
6.1. Product scope
Target user profile:
- Has a need to manage a significant number of animals
- Prefers desktop apps over other types
- Can type fast
- Prefers typing to mouse interactions
- Is reasonably comfortable using CLI apps
Value proposition:
- Zookeepers have to account for a large number of animals and their statuses (health, feed times etc).
- It is easy to lose track without a structured database.
- We have thus decided to morph the app into a tracker for an individual zookeeper.
- Easier to transfer a large amount of animal information when zookeepers change shifts.
- Manage animals faster than a typical mouse/GUI driven app.
6.2. User stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
* * * |
new zookeeper | see usage instructions | refer to instructions when I forget how to use the App |
* * * |
zookeeper | add an animal entry | keep track of a new animal under my care |
* * * |
zookeeper | delete an animal entry | remove animals from my care |
* * * |
zookeeper | retrieve the information of all the animals | have a look at which animals are under my duty |
* * * |
zookeeper | load a save file | keep track of all the animals I have added |
* * * |
zookeeper | save all the information when I need to | |
* * * |
zookeeper | exit the program after I have finished using it | |
* * |
zookeeper | search for a specific animal | filter through the large number of animals without viewing the entire list |
* * |
zookeeper | quickly edit the data of certain animals | avoid deleting and adding the animal to do so |
* |
zookeeper with many animals in the ZooKeepBook | sort animals by name and type | locate a specific animal easily |
* |
experienced user | use shortcut commands to carry out tasks | save time without needing to type the full length commands |
6.3. Use cases
(For all use cases below, the System is the ZooKeepBook
and the Actor is the user
, unless specified otherwise)
Use case: UC01 - Add an animal
MSS
-
User specifies the add command with name, ID and species of animal
-
ZooKeepBook adds the animal
-
ZooKeepBook shows the new animal added
-
ZooKeepBook refreshes to show the updated list
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
2a. The given ID is already taken
-
2a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
Use case: UC02 - Delete an animal
MSS
-
User specifies the delete command with ID of animal
-
ZooKeepBook deletes the animal
-
ZooKeepBook shows the deleted animal
-
ZooKeepBook refreshes to show the updated list
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
2a. The given ID does not exist or is out of range
-
2a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
Use case: UC03 - List all animals
MSS
-
User specifies the list command
-
ZooKeepBook displays list of all existing animals
Use case ends
Use case: UC04 - Exit program
MSS
-
User specifies the exit command
-
ZooKeepBook quits
Use case ends
Use case: UC05 - View available commands
MSS
-
User specifies the help command
-
ZooKeepBook displays list of all available commands
Use case ends
Use case: UC06 - Find animals based on keywords
MSS
-
User specifies the find command with the keywords (case-insensitive) regarding an animal’s name, id, species, medical condition or feed time
-
ZooKeepBook searches for all animals with any of the exact keywords
-
ZooKeepBook shows the list of animals with any of those keywords
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
Use case: UC07 - Sort all animals
MSS
-
User specifies the sort command and the specific category (name, id, feedtime or medical)
-
ZooKeepBook sorts the animals according to the category
-
ZooKeepBook shows a success message
-
ZooKeepBook refreshes to show the sorted list
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
Use case: UC08 - Undo last command
MSS
-
User specifies the undo command
-
ZooKeepBook reverts to the state before last command was made
-
ZooKeepBook shows a success message
Use case ends
Extensions
-
2a. There is no previous state to revert to
-
2a1. ZooKeepBook shows an error message
-
Use case ends
-
Use case: UC09 - Redo last undo
MSS
-
User specifies the redo command
-
ZooKeepBook reverts to the state before undo command was made
-
ZooKeepBook shows a success message
Use case ends
Extensions
-
2a. There is no previous state to revert to
-
2a1. ZooKeepBook shows an error message
-
Use case ends
-
Use case: UC10 - Save current animal data
MSS
-
User specifies the snap command with the appropriate file name
-
ZooKeepBook creates a snapshot of the current ZooKeep book data which is saved as a file with the user specified file name
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
1b. An invalid file name is entered
-
1b1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
Use case: UC11 - Append data to an animal
MSS
-
User specifies the append command with the animal ID and any relevant medical conditions and/or feed times to be added
-
ZooKeepBook appends the entered animal conditions and/or feed times to the specific animal
-
ZooKeepBook shows the edited animal details
-
ZooKeepBook refreshes to show the updated list
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
2a. The given ID does not exist or is out of range
-
2a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
2b. No details are entered or the appended details result in no change to the animal
-
2b1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
Use case: UC12 - Replace the data of an animal
MSS
-
User specifies the replace command with the animal ID and any intended changes in the animal details
-
ZooKeepBook replaces the current animal details with the entered changes
-
ZooKeepBook shows the updated animal details
-
ZooKeepBook refreshes to show the updated list
Use case ends
Extensions
-
1a. The command is incorrectly formatted
-
1a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
2a. The given ID does not exist or is out of range
-
2a1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
-
2b. No details are entered or the entered details result in no change to the animal
-
2b1. ZooKeepBook shows an error message
-
Use case resumes at step 1
-
6.4. Non-Functional Requirements
- Should work on any mainstream OS as long as it has Java
11
or above installed. - Should be able to hold up to 1000 animals 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.
- The system should work on both 32-bit and 64-bit environments.
- The system is expected to show data persistence.
- The system should allow different users to access the same data to allow ease of transfer during shift changes.
- The system should have clear, complete and comprehensive documentation of all available commands and/or features by the end of the project.
- The system should be extensible such that new commands or features can be easily added to it if needed.
- The system should cope with emergency situations and allow for data archiving in case users need to retrieve important data stored in older versions of the ZooKeepBook.
- The system should respond to user requests (e.g. load data, add new animals) within 2 seconds, unless an error occurs.
- The system should be intuitive enough such that new staff are able to adapt quickly and use the app smoothly within a short time frame.
- The system should be user-friendly and implement helpful features to assist careless users, such as allowing for the undoing and redoing of commands.
- The system should be backward compatible with data produced by its earlier versions.
- The system should be flexible and allow its users some degree of freedom, by allowing them to enter certain command parameters in any order they wish.
- The project is expected to adhere to the schedule of the CS2103/CS2103T tP timeline which requires weekly deliverables and increments.
- The project is not required to sort and arrange tasks among all staff or ensure efficient task allocation and completion.
6.5. Glossary
- Mainstream OS: Windows, Linux, Unix, OS-X
- Data persistence: data provided by the user can be saved and updated to the hard drive, and can also be loaded once system is booted up again
- Data archiving: the process of moving data that is no longer actively used to a specified directory for long-term retention.
7. Appendix: Instructions for manual testing
This section provides instructions for testing the application manually.
7.1. Launch and shutdown
7.1.1. 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.
7.1.2. 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.
7.2. Deleting an animal
-
Test case:
delete 123
Expected: The animal with an ID of 123 deleted from the list. Details of the deleted animal shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete 0
Expected: No animal 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 smaller than all 3 digit numbers or larger than all 6 digit numbers)
Expected: Similar to previous.
7.3. Saving data
7.3.1. Dealing with missing/corrupted data files
-
To simulate a missing/corrupted data file, delete the
data/zookeepbook.json
file. -
Re-launch the app by double-clicking the jar file.
Expected: The sample ZooKeepBook will be loaded as the newdata/zookeepbook.json
file.
7.3.2. Auto-saving feature
-
After launching the application, perform actions that edit the ZooKeepBook, such as
add
ordelete
. Close the window. -
Re-launch the application. The changes that you just made should be reflected in the ZooKeepBook UI.