By: AY1920S1-CS2103T-T12-3
Since: Sep 2019
Licence: MIT
- 1. Introduction
- 2. Setting up
- 3. System design
- 4. Implementation
- 5. Documentation
- 6. Testing
- 7. Dev Ops
- Appendix A: Product Scope
- Appendix B: User Stories
- Appendix C: Use Cases
- Appendix D: Non Functional Requirements
- Appendix E: Glossary
- Appendix F: Product Survey
- Appendix G: Instructions for Manual Testing
1. Introduction
This section specifies the purpose of this document and design goals of Athletick.
1.1. Purpose
This document describes the software architecture and system design of Athletick, a team management desktop application for coaches and team captains of timing-based performance sports. It also includes some of the design considerations for the implementation of Athletick’s features.
The intended audience of this document includes the developers and software testers of Athletick.
Note the following symbols and formatting used in this document:
This symbol indicates important information. |
command
|
A grey highlight (called a mark-up) indicates that this is a command that can be typed into the command line and executed by the application. |
component
|
Green text with grey highlight indicates a component, class, object or method in the architecture of the application. |
1.2. Design goals
Athletick was developed as part of CS2103T, a software engineering module taken in the National University of Singapore. We were tasked to morph a generic address book application that manages contacts into an application that manages something else. At the end of the project, it should be ready to be continued by future developers.
As part of the project constraints, the input to Athletick needs to be primarily Command-Line Interface (CLI). Non-CLI inputs will reduce the suitability of the product to our target users. Taking this into consideration, the following principles guide the design of Athletick:
-
Detailed Command Syntax Instructions
In order to make Athletick more user-friendly, we have provided detailed command syntax instructions whenever users enter an erroneous command, allowing them to correct their errors on the fly. This helps users to maintain their workflow without having to switch back and forth between the application and the user guide, enabling them to complete their tasks more efficiently.
-
Optimised Performance
Athletick should be able to hold up to 1000 athletes, attendance and performance records without a noticeable sluggishness in performance for typical usage. To achieve this, we have used optimal data structures for storing and retrieval of data.
-
Designer Friendly
As Athletick is intended for future student developers like us to make modifications and extensions to its behaviour, adhering to the high-level design architecture strictly was a necessity. This translates to extensive use of abstractions for code clarity. Additionally, we provided Javadoc comments for our classes and methods for developers to understand how they work.
2. Setting up
Refer to the guide here.
3. System design
This section introduces the high-level design of Athletick and gives you a basic understanding of how each component operates and interacts with one another.
3.1. Architecture
The Architecture Diagram given above explains the high-level design of Athletick. Given below is a quick overview of each component.
-
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 (refer to the class diagram given below) defines it’s API in the
Logic.java
interface and exposes its functionality using the LogicManager.java
class.
How the architecture components interact with each other
The Sequence Diagram below shows how the components interact with each other for the scenario where the user issues the command delete 1
.
delete 1
CommandThe sections below give more details of each component.
3.2. UI component
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
,
ResultDisplay
, PersonListPanel
, 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
API :
Logic.java
-
Logic
uses theAthletickParser
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 a person). -
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.
delete 1
Command
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.
|
3.4. Model component
API : Model.java
The Model
,
-
stores a
UserPref
object that represents the user’s preferences. -
stores the Address Book data.
-
exposes an unmodifiable
ObservableList<Person>
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.
As a more OOP model, we can store a Tag list in Athletick , which Person can reference. This would
allow Athletick to only require one Tag object per unique Tag , instead of each
Person needing their own Tag
object. An example of how such a model may look like is given below. |
3.5. Storage component
API : Storage.java
The Storage
component saves the following data in json format and reads it back as objects when
a new session of Athletick is started.
-
UserPref
data -
Athletick
data (athlete list) -
Performance
data (Event
andRecord
) -
TrainingManager
data (Training
)
Performance
and TrainingManager
rely on JsonAdaptedPerson
as well, since a
performance and training record also stores the athlete it is referring to.
3.6. Common classes
Classes used by multiple components are in the seedu.addressbook.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented. We have included our design considerations for you to understand our decision making processes.
4.1. Training feature
Athletick allows users to record training information like the date of training and an athlete’s attendance. This
is done using a training
command. With this information recorded, Athletick allows users to get the team’s
overall attendance rate, and get an overview of all training sessions in a month.
4.1.1. Implementation
A Training
class stores the training information. To facilitate management of trainings, a
TrainingManager
class stores all the Training
sessions. The class diagram below shows the
interaction of different components to produce the training feature.
A training session is represented by a Training
class and it contains information like the date of
training and training attendance. The AthletickDate
class represents the date of a training session in
Training
. This class is shared across both the frontend and backend of the application, allowing training
information to be used in other features that use AthletickDate
. A HashMap<Person, Boolean>
represents attendance in
Training
and indicates whether a Person
has attended that training session. If a
Person
attended, the value associated with him in the HashMap<Person, Boolean>
will be true,
and false if he did not attend.
The TrainingCommand
is an abstract class that extends the Command
class and allows users to
record training sessions. Users have the ability to add training sessions by indicating members present or members
absent using the training
or training -a
commands. The TrainingCommandPresent
and
TrainingCommandAbsent
are classes that extend TrainingCommand
which allows for this
polymorphism. They are created by the TrainingCommandParser
class.
A TrainingManager
stores and manages all Training
sessions in Athletick. It contains a
list which is used to maintain information of multiple trainings. A Training
is added to this list
whenever a user executes a training
command. The activity diagram below shows how training information is
stored after a user executes the training
command.
training
commandTrainingManager
also provides functions for users to calculate the attendance rate of one individual, or
the entire team. The following operations are used for this feature:
-
TrainingManager#getPersonAttendanceRateString
— Returns the person’s overall attendance rate in String format. -
TrainingManager#getAttendanceRateOfAll
- Returns a list of everyone’s attendance rate.
These operations are used by the select
, attendance
and view attendance
commands. The following sequence diagram
shows how the TrainingManager
provides other components with attendance rates.
view attendance
command gets attendance rateTrainingManager
also allows users to get the attendance of one particular training using the following
operation:
-
TrainingManager#getTrainingAttendanceListOnDate
— Returns training attendance on the specified date.
The sequence diagram below shows a use case of how training attendance is obtained from TrainingManager
when a calendar
command is executed.
calendar
command gets training attendance4.1.2. Design Considerations
This section contains some of our considerations for the training feature.
Aspect: How to store attendance information of an individual.
Alternative 1: Make extensions to the |
Alternative 2 (Current Choice): Create separate classes to manage training information. |
|
Pros |
It is easy to implement. |
Allows storing of specific training information without depending on the |
Cons |
Violates software engineering principles (single responsibility principle) and is not useful when we want more detailed information (attendance on specific date) about a training session. |
More time needed to design system architecture. |
Reason for choosing alternative 2: Training
and TrainingManager
are created as standalone
classes to contain training information. We intend to introduce new features (e.g. training category) in the future and this
implementation allows us to easily do so.
Aspect: Which data structure to store training attendance.
Alternative 1: Use a linked list to store training attendance. |
Alternative 2 (Current Choice): Use a hash table to store training attendance. |
|
Pros |
Most intuitive way to maintain training attendance. Also provides us with functions to easily access and edit data. |
Makes obtaining information much quicker. |
Cons |
Accessing attendance and attendance rate of one person takes more time. |
Requires more effort to maintain and requires coding of new functions to edit data. |
Reason for choosing alternative 2: The select
and attendance
commands require the attendance rate of only one
person and a hash table provides us with the fastest access time to access attendance information of one person.
Aspect: How to edit training information.
Alternative 1 (Current Choice): Edit by replacing an existing training with a new training on the same date. |
Alternative 2: Create a command to support editing of training. |
|
Pros |
Users will not need to type lengthy edit commands. |
More intuitive to a user who wants to edit. |
Cons |
Unable to support multiple trainings on same date. |
Users have the option to edit date, attendance and even add a person which will require lengthy commands. |
Reason for choosing alternative 1: Editing training information would require typing long commands which will be very
time-consuming and this defeats the purpose of having a command line interface. Editing training by replacing an old
one with the training
command makes it editing much quicker.
4.2. Performance feature
Athletick allows users to record an athlete’s performance details from timed trials. With this information recorded, Athletick allows users to get an overview of the team’s capability and progress in specific events.
4.2.1. Implementation
This section explains how Performance
is implemented in Athletick.
It is split into 4 sections.
-
Overview
-
Adding and deleting of
Event
-
Adding and deleting of
Record
-
Viewing of
Event
andRecord
Overview
ModelManager
has a Performance
, which has a UniqueEventList
.
Every Event
in Athletick is stored in this UniqueEventList
.
The class diagram below shows how the different components mentioned interact with one another.
As the name suggests, all Event
names are unique in UniqueEventList
.
This is ensured by UniqueEventList#contains()
that checks whether there is an Event
with the same name before the Event
is added.
Every event has its own HashMap
where performances under this event are stored.
The key of the HashMap is the Person
that the performance records will be under, while the value
of the HashMap is a list of Record
s under the Person
.
This structure allows each Person
to have multiple Record
s stored in Athletick so
their progress over time can be analysed using the AthletickDate
and Timing
attributes in Record
. Additionally, an athlete’s records can be easily retrieved by calling the
HashMap#get()
method.
Event
s are added using the EventCommand
, and Record
s are added using the
PerformanceCommand
. In these commands, changes to UniqueEventList
are called through
Model
in EventCommand#execute()
and PerformanceCommand#execute()
since
Model
carries a common copy of all the data stored in Athletick.
The Observer Pattern is adopted when displaying Performance
data through the UI
.
Model
exposes an unmodifiable ObservableList<Event>
through
Model#getPerformance
that returns a ReadOnlyPerformance
. It can be 'observed'
and is updated accordingly when data in Performance
changes.
Function 1: Adding and Deleting of Event
The following sequence diagram illustrates what happens in Logic
and Model
when in an
example scenario when event freestyle 50m
is given as a user input (ie. when the user adds the freestyle
50m
event).
Deleting an event (with DeleteEventCommand
) does the opposite. The input delete -e freestyle
50m
will call Model#deleteEvent()
, after making sure the event exists in Athletick by getting a
boolean from Model#hasEvent()
.
Function 2: Adding and Deleting of Record
Operations for Record
- adding and deleting - work similarly to that of Event
as well,
except there are more methods involved as there is a greater degree of nesting.
The workflow for adding a record can be illustrated by the Activity Diagram below.
Function 3: Viewing of Event and Record
Users can also view all Record
s under an Event
using view records e/EVENT_NAME
.
The following sequence diagrams illustrate how the Logic
, Ui
and
Model
work together when Record
viewing is executed.
4.2.2. Design Considerations
This section explains the factors that we took into consideration when deciding on how different
aspects of Performance
should be implemented.
Aspect: Method of storing performance records for athletes.
Performance records are currently stored in a list for each athlete. Each list is saved as a value for the athlete key in a Performance HashMap.
Alternative 1 (Current Choice): Use a HashMap of Persons as keys and a list of Records as values. |
Alternative 2: Create a class that has Persons and list of Records as attributes and store instances of this class in a list. |
|
Pros |
|
|
Cons |
|
|
Reason for choice of Alternative 1:
-
Retrieving from a HashMap is fast, which fulfils one of our non-functional requirements of being able to support a database of 1000 athletes
-
Using an athlete-records relationship is similar to the key-value relationship in HashMap so the existing methods that are in the HashMap API are relevant
Aspect: Method of displaying events and records to users.
Viewing events and records are separate commands in Athletick.
To view events, the command is view performance
. Users will be shown a list of all the events they have
in Athletick. To view records under a certain event, the command is view records EVENT_NAME
. Users will
be shown a graph on each athlete’s records under this event.
Alternative 1 (Current Choice): Display events and records separately. |
Alternative 2: Display all records under all events. |
|
Pros |
|
|
Cons |
|
|
Reason for choice of Alternative 1:
-
Allowing users to look at the records under their event of interest gives them more control over what they want to see
-
Navigating from event overview to a particular event mimics how people navigate in apps - tapping on a chat title (in this case, viewing records for a particular event), to see the whole conversation (record details for a particular event)
4.3. Calendar feature
To allow users to retrieve training and performance records using the date they were recorded on, Athletick has a calendar feature which provides 2 main functions:
-
Displays an overview of training and performance records in a selected month
-
Displays training and performance records entered on a specific date
4.3.1. Implementation
The implementation of the above functions will be described separately in this section.
Function 1: Displays an overview of training and performance records in a selected month
There are 2 commands that users can issue to perform function 1:
-
view calendar
: Displays calendar for the current month. -
calendar MMYYYY
: Displays calendar for the month specified by the user.
The following sequence diagram shows you how the calendar MMYYYY
(e.g. calendar 012019
where 012019
corresponds to January 2019) command works.
UI
and Logic
components for the calendar 012019
CommandUpon completion of the above execution, the calendar for January 2019 will be displayed to the user.
The view calendar
command is similar except that displayCalendar(CommandResult)
is called instead of displayCalendarWithDate(CommandResult)
and the CalendarPanel
class is instantiated without an AthletickDate
specified by the user. The calendar displayed to the user will reflect the current month and year since date is not specified by the user.
The following activity diagram summarises what happens when a user wants to perform function 1.
Function 1 is facilitated by the CalendarPanel
class. It extends UiPart<Region>
and represents the calendar using a GridPane
with dimensions of 7 by 6 (42 cells). Additionally, it implements the following operations:
-
CalendarPanel#retrieveCurrentDate()
— Retrieves the details of today’s date to be used as the title of the calendar feature and for rendering the displayed month on the calendar when the user does not provide a specific month to view. -
CalendarPanel#retrieveProvidedDate(AthletickDate)
— Retrieves the details of the date provided by the user for rendering the displayed month on the calendar. -
CalendarPanel#initialiseSelectedDate()
— Fills up all the 42 cells of theGridPane
with their respective days based on the selected month by the user. Days of the previous and next month used to fill up the remaining cells are marked in a lighter colour.In addition, days with training or performance records will be marked with a small green or purple dot indicator respectively.
These operations are performed when an instance of the CalendarPanel
class is created in the MainWindow
class. An instance of CalendarPanel
is created when the CommandResult
obtained in MainWindow
after the execution of the user’s command contains a Feature
corresponding to a calendar and an optional AthletickDate
.
The sequence diagram below shows you what happens when the CalendarPanel
class is instantiated.
UI
and Model
components when CalendarPanel
is instantiatedWith reference to the above diagram, if hasTrainingOn(AthletickDate)
returns true, a green dot indicator will be added to the cell of the GridPane
. Similarly, if hasPerformanceOn(AthletickDate)
returns true, a purple dot indicator will be added.
Upon completion of the above execution, all 42 cells GridPane
will be filled with a number corresponding to the day of the month. Days with training or performance records will be marked with a green or purple dot indicator respectively. The following diagram depicts how each individual cell will look like.
Function 2: Displays training and performance records entered on a specific date
In order to perform function 2, the user issues the calendar DDMMYYYY
command (e.g. calendar 01012019
where 01012019
corresponds to 1st January 2019).
The following sequence diagram shows you how the calendar DDMMYYYY
(e.g. calendar 01012019
) operation works.
UI
and Logic
components for the calendar 01012019
commandUpon completion of the above execution, the attendance and performance records for 1st January 2019 will be displayed to the user.
The following activity diagram summarises what happens when a user issues the calendar DDMMYYYY
command.
calendar DDMMYYYY
commandFunction 2 is facilitated by CalendarDetailPanel
. It extends UiPart<Region>
and displays the attendance and performance records for a date specified by the user. Additionally, it implements the following operations:
-
CalendarDetailPanel#initialiseAttendanceData()
— Retrieves and displays attendance records recorded on the specified date. -
CalendarDetailPanel#initialisePerformanceData()
— Retrieves and displays the performance records recorded on the specified date.
These operations are performed when an instance of CalendarDetailPanel
is created in the MainWindow
class. An instance of CalendarDetailPanel
is created when the CommandResult
obtained after executing the user’s command contains a Feature
corresponding to a calendar and an AthletickDate
.
The sequence diagram below shows you what happens when the CalendarDetailPanel
class is instantiated.
UI
and Model
components when CalendarPanel
is instantiatedUpon completion of the above execution, training and performance records recorded on the specified date will be displayed to the user.
4.3.2. Design considerations
This section contains some of our design considerations for the calendar feature.
Aspect: Whether to display information using a monthly calendar or a list only containing dates in a month with training or performance records
Alternative 1 (Current Choice): Use a monthly calendar |
Alternative 2: Use a monthly list |
|
Pros |
Displays information more clearly especially when users have a large number of training and performance records in a month |
Displays information more concisely if users have a small amount of training and performance records in a month |
Cons |
Increases difficulty of implementation |
Displays information in rows and columns which is no better than using Excel |
Reasons for choice of alternative 1:
-
Alternative 1 displays information more clearly when users have a large amount of training and performance information, which is a probable scenario in the case of sports teams. In contrast, alternative 2 uses a list similar to Excel which we are trying to improve upon.
-
Alternative 1 abides by our design principle to keep Athletick designer friendly since future developers can expand upon it and implement more date-related functionalities.
Aspect: How to display calendar for a month
Alternative 1 (Current Choice): Display using a fixed 7 by 6 |
Alternative 2: Display using a variable sized |
|
Pros |
Emulates implementation by other calendar applications and easier to implement (e.g. Google Calendar) |
Maximises usage of space in the application window |
Cons |
Displays information of previous and next month which users may not be interested in |
Increases difficulty of implementation |
Reasons for choice of alternative 1:
-
Alternative 1 is easier to implement since the dimensions of the calendar are fixed so we do not have to recalculate it constantly. The ease of implementation is important given the tight deadlines we have to contend with in our software engineering module.
-
Alternative 1 emulates the implementation of other successful calendar applications (e.g. Google Calendar) so we do not have to reinvent the wheel.
Aspect: How the user can display the attendance and performance data on a specific date
Alternative 1 (Current Choice): Use one |
Alternative 2: Use two separate commands to view attendance and performance records separately on the specified date |
|
Pros |
Makes access of data more efficient |
Allows users to have more control over what data is displayed |
Cons |
Displays both attendance and performance records on the specified date all the time |
Requires more flags to be added to the command syntax which makes it more complex |
Reasons for choice of alternative 1:
-
Alternative 1 is more user-friendly as it reduces the number of commands users have to remember in order to access the information they want to see. In addition, attendance and performance records are displayed into separate sections in the window so the information will not be cluttered.
4.4. Select feature
The select
feature allows user to view the profile of a selected athlete.
4.4.1. Implementation
The implementation of the select
feature consists of two parts, mainly the implementation of the command and the
implementation of the UI.
The implementation of the command is facilitated by SelectCommand
class. It extends
Command
and parses the arguments using SelectCommandParser
. It implements one operation:
-
CommandResult#execute()
— Executes the selectCommand which returns the athlete selected to be displayed in the UI.
The implementation of the UI portion for the select
feature is facilitated by InformationDisplay
. It
extends
UiPart<Region>
and displays the personal information of the selected athlete. Additionally, it implements the
following operations:
-
InformationDisplay#displayPersonalInfo()
— Displays the personal information of the selected athlete such as the name, email, address, phone number and other personal details. -
InformationDisplay#performanceDisplay()
— Displays the performance of the selected athlete, which includes the event, best performance and most recent performance.
An example usage scenario is given below which elaborates how the select
feature behaves at each step.
Step 1. The user executes the select 3
command. The command is then parsed by SelectCommandParser
which
creates
an instance of SelectCommand
. SelectCommand
retrieves the athlete based on the index of the list
panel on the left.
When the command is executed, the athlete selected at the specified index will be stored in ModelManager
as
selectedPerson
using the operation Model#storePerson(Person)
.
Step 2. After the command has been executed, the selected athlete is retrieved in the MainWindow class. It checks whether an athlete has been selected and displays the selected athlete’s personal information.
The diagram below summarises the steps of the example scenario when a user executes the select
command:
select
command executionThe implementation was done this way because the Ui component interacts with both the Logic and Model component.
Firstly, the Ui component takes in the input from the user and allows SelectCommandParser
in Logic component
to parse the argument.
After the argument has been parsed, the athlete is stored in the Model component which houses most of the data in the
app. The Ui listens for any changes made to the Model data, and updates the Ui to display the selected athlete.
The following sequence diagram shows how the select
feature works:
select
Command4.4.2. Design considerations
There were some decisions that I had to make as I was designing the select
feature and had to compare which methods
would better suit the application. The following consists of the design considerations for the select
feature.
Aspect: How the personal information of the selected athlete will be displayed
There were a few ways how the personal information of the selected athlete could be displayed and the following alternatives are some of the considerations I had when implementing.
Alternative 1 (current choice): Displaying it in a feature box. |
Alternative 2: Displaying it in a tab form. |
Alternative 3: Displaying via a pop-up. |
|
Pros |
|
|
|
Cons |
|
|
|
Reason: Alternative 1 was chosen because it utilises more of the command line interface and we wanted to steer away from the use of the mouse. Even those the aesthetic might not be as good as alternative 2 and 3, I felt that it was a better choice as it was in line with the other features that my group mates were going to implement.
Aspect: How to select an athlete
There were two ways on how an athlete could be selected and it was between choosing by index or by name which I had to consider.
Alternative 1 (current choice): Choosing by the index number. |
Alternative 2: Choosing by name. |
|
Pros |
|
|
Cons |
|
|
Reason: In the end, I went with alternative 1 because it was more intuitive to use and was in line with some of the
other functions such as DeleteCommand
or FindCommand
which also uses index. It also reduces the
need to type out the full name of the selected athlete.
4.5. Undo / Redo feature
The undo
command enables users to undo their previous commands while the redo
command enables users to redo their
undone commands.
4.5.1. Undo Implementation
The undo
command is facilitated by the HistoryManager
. HistoryManager
holds the
states of Athletick
, Attendance
and Performance
, which are kept in
their respective stacks governed by HistoryManager
. Furthermore, HistoryManager
also
holds the Command
stack that keeps track of the commands executed by the user.
Each time after the user executes a command, the command will be pushed to the
Command
stack. Also, following the execution of the command,
changes to either Athletick
,Attendance
or Performance
will result in the new state being pushed into their respective stacks.
Given below is an example usage scenario on how the undo mechanism behaves at each step.
Step 1. The user launches the application for the first time. The HistoryManager
will be
initialised with the initial Athletick
, Attendance
and
Performance
state pushed to the respective stacks.
Step 2. The user executes the delete -p 3
command to delete the 3rd person in the Athletick
list. The
delete command will be pushed into the Command
stack. After that,
since the delete -p 3
command only alters the Athletick
state, the new Athletick
state will then be pushed to the Athletick
stack while the Attendance
and
Performance
stacks are left untouched as their states remain the same.
delete -p 3
commandStep 3. The user now decides that deleting the 3rd person in the list was a mistake, and decides to undo the action
by executing the undo
command. The undo
command then executes the undo
method in the
ModelManager
. This pops the latest command from the Command
stack and the latest Athletick
state from the Athletick
stack.
It then peeks at the Athletick
stack to retrieve the Athletick
state
before delete -p 3
command was executed.
undo
commandStep 4. After retrieving the Athletick
state before delete -p 3
command
was executed, we then reset the Athletick
state to this retrieved
Athletick
state. As such, the previous command will then be undone.
The following sequence diagram shows how the undo operation works:
4.5.2. Redo Implementation
The redo
command is similarly facilitated by the HistoryManager
. HistoryManager
also holds the undone states of Athletick
, Attendance
and Performance
,
which are kept in their respective undone stacks governed by HistoryManager
. Furthermore,
HistoryManager
also holds the undone Command
stack that keeps track of the commands
undone by the user.
Each time an undo
command is executed succesfully, the undone Command
will be pushed
to the undone Command
stack and the respective undone states of Athletick
, Attendance
or Performance
, if affected, will be pushed to their respective undone states.
Following that, how the redo
command works is very similar to how the undo
command works.
As such, you can also refer to the diagrams in the
Undo
Implementation.
The activity diagram for redo
command is as follows:
redo
command4.5.3. Design Considerations
This section describes the pros and cons of the current and other alternative implementations of the undo and redo features.
Aspect: How undo & redo executes
Alternative 1 (Current Choice): Keep states of |
Alternative 2: Individual command knows how to undo/redo by itself |
|
Pros |
|
|
Cons |
|
|
Reason why we chose alternative 1:
Even though the memory usage of Alternative 2 is lesser, we do not feel that this benefit of lesser memory usage outweighs the tedious cost of implementing the alternative.
Furthermore, as we realise that each time the application starts, the memories of the states are cleared. This means that the cost of having alternative 1 is significantly lesser, as the memories of the states do not accumulate. As such, we decided to go with the first alternative.
4.6. Adding/editing photo feature
The sub feature of AddCommand
and EditCommand
allows the inclusion of photo for an athlete.
4.6.1. Implementation
The sub feature is facilitated by Photo
. It is similar to the other features such as Name
and
Phone
which uses a prefix i/
followed by the file name (e.g. i/default.png
). Prior to adding the photo
of an athlete, the image file that is going to be used has to be in the images
folder which will be generated when the
jar file is executed. Photo
takes in the file name as a String
and retrieves the photo to be added
or edited from the images
folder.
The file name of the images is restricted to alphanumerics only and the file format that will be used is .png .
This is done to keep the file name simple.
|
4.6.2. Design Consideration
The following consists of some of the design consideration when I was designing this sub-feature.
Aspect: Regular expression for the file name
Alternative 1 (current choice): To use alphanumerics only. |
|
Pros |
Pros: Keeps it simple without the confusion of special characters. |
Reason: Alternative 1 was chosen because it simplifies the parsing of the filename and reduces the error it might have if special characters were included.
4.7. Filter feature
The filter command enables filtering of athletes based on their tags. Users are able to filter by multiple tags, and any athlete that has any of the given tags will be in the results.
4.7.1. Implementation
Filter makes use of a TagMatchesPredicate
class to determine if the athlete has tags matching the user input.
Given below is the Sequence Diagram to show how Logic
and Model
are involved when an
example input of filter captain freestyle
is called.
4.7.2. Design considerations
This section explains the factors that we took into consideration when making decision on how
FilterCommand
should be implemented.
Aspect: Method of determining an athlete match when multiple tags are given.
Given an example search of filter captain freestyle
, athletes will be shown in the results if they
contain either the captain
or freestyle
tag. They need not have both captain
and freestyle
.
Alternative 1 (Current Choice): Match athletes who contain either tag. |
Alternative 2: Match athletes who contain every tag. |
|
Pros |
|
|
Cons |
|
|
Reason for choice of Alternative 1:
Our choice of "lenient" filtering may give users results that they may not be interested in especially if they are looking for very specific athletes. However, we find that it is a good compromise for users who want this "lenient" filtering as the athlete’s tags will be listed in the search as well, so specific athletes can be found from this filtered list.
4.8. Sort Command
The sort
command sorts the displayed list of athletes in alphabetical order. As new athletes are added to the bottom of the list, the sort
command is used after to reorder the athlete list.
4.8.1. Implementation
The sort
command makes use of a PersonNameComparator
that orders athletes in alphabetical order by comparing their names. The comparison is case-insensitive.
The following sequence diagram shows how the sort
operation works:
sort
CommandWith reference to the diagram above, when the user issues the sort
command, a SortCommand
object s
is created. s
is then executed by LogicManager
, which calls the sortByName()
method in LogicManager
. An instance of PersonNameComparator
is then created and is used by the sortByName(PersonNameComparator)
method in Athletick
to sort the observable internalList
in UniquePersonList
. Upon completion of the above execution, the sorted list of athletes would be displayed immediately to the user.
To support sorting by more attributes (e.g. attendance rate/performance) in the future, you can simply create a new class that implements the Comparator
interface which compares athletes by that attribute instead. After which, you have to edit the sort
command syntax to allow users to indicate how they want their list to be sorted.
4.8.2. Design considerations
This section contains some of our design considerations for the sort command.
Aspect: When should the athlete list should be sorted
Alternative 1 (Current Choice): Sort address book after user issues the |
Alternative 2: Sort address book persistently in alphabetical order |
|
Pros |
|
|
Cons |
|
|
Reason for choice of alternative 1:
-
Alternative 1 allows users to view their newly added athletes to ensure their details are correct before they are sorted into their correct positions alphabetically. This is important especially when the athlete list is very long.
-
Alternative 1 abides by our design principle to keep Athletick designer friendly since future developers can expand upon it to allow sorting by other attributes. On the other hand, alternative 2 does not provide much room for future expansion.
4.9. Logging
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 4.10, “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 the App -
FINE
: Details that is not usually noteworthy but may be useful in debugging e.g. print the actual list instead of just its size
4.10. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
5. Documentation
Refer to the guide here.
6. Testing
Refer to the guide here.
7. Dev Ops
Refer to the guide here.
Appendix A: Product Scope
Target user profile:
-
Team coaches for time-based, competitive sports
-
Has a need to manage a significant number of team members
-
Prefer desktop apps over other types
-
Can type fast
-
Prefers typing over mouse input
-
Is reasonably comfortable using CLI apps
Value proposition: Manage team details faster and more accurately than a typical mouse/GUI driven app
Appendix B: User Stories
Priorities: High (must have) - * * *
, Medium (nice to have) - * *
, Low (unlikely to have) - *
Priority | As a … | I want to … | So that I can… |
---|---|---|---|
|
Team coach who values commitment |
Input attendance of my team |
Keep track of their attendance rate and commitment level |
|
Efficient team coach |
Take attendance quickly |
Focus on coaching my team |
|
Team coach |
Track performance of my team |
Know how to help them improve |
|
Motivational Team coach |
Performance data analysis of the performance of my team |
Provide detailed feedback to my athletes |
|
Detailed team coach |
Retrieve past training and performance records on a specific date |
Know what happened on a specific date |
|
Team coach |
View profile of specific members |
Monitor their individual progress |
|
Careless user |
Undo my previous commands |
Redo any mistakes |
|
New user |
Know the available commands |
Be able to use all the app functionalities |
|
Team coach |
Assign tags to my team members |
Differentiate roles of team members |
|
Team coach |
Filter out my best performers for each event |
Plan my team to send for competitions |
|
Coach who is in-charge of multiple teams |
Add multiple teams |
Manage my teams separately |
|
Forgetful coach |
See past commands issued |
Know what changes I have made |
|
User who wants customisation |
Change the app’s colour |
Customise the app according to my preference |
|
Coach who wants fit players |
Filter players by overweight BMIs |
Single them out and get them to lose weight |
Appendix C: Use Cases
(For all use cases below, the System is Athletick
and the Actor is the user
, unless specified otherwise)
System: Athletick
UC1 - Marking attendance of players
Actor: User
MSS
-
User requests to list persons
-
Athletick shows a list of persons
-
User keys in players who attended training
-
Athletick saves the training session
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. Athletick shows an error message.
Use case resumes at step 2.
-
UC2 - Delete person
Actor: User
MSS
-
User requests to list persons
-
Athletick shows a list of persons
-
User requests to delete a specific person in the list
-
Athletick deletes the person
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. Athletick shows an error message.
Use case resumes at step 2.
-
UC3 - Key in Performance of a Player
Actor: User
MSS
-
User requests to list persons
-
Athletick shows a list of persons
-
User requests to tag a performance to a specific person in the list
-
Athletick updates the player’s performances
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. Athletick shows an error message.
-
-
3b. Input event does not exist
-
3b1. Athletick shows an error message
-
-
3c. Timing is invalid
-
3c1. Athletick shows an error message
Use case resumes at step 2.
-
UC4 - View a player’s profile
Actor: User
MSS
-
User requests to list persons
-
Athletic shows a list of persons
-
User request to select a specific person in the list
-
Athletick shows the profile of the person
Use case ends.
Extensions
-
2a. The list is empty.
Use case ends.
-
3a. The given index is invalid.
-
3a1. Athletick shows an error message.
Use case resumes at step 2.
-
UC5 - Add a person
Actor: User
MSS
-
User keys in details of person to be added
-
Person is added to the list
Use case ends.
Extensions
-
1a. Details are invalid (eg. not all fields are filled up)
-
1a1. Athletick shows an error message.
Use case ends.
-
-
1b. Person has already been added
-
1b1. Athletick shows an error message.
Use case ends.
-
UC6 - Undo a command
Actor: User
MSS
-
User calls for undo
-
Most recent command is undone
Use case ends.
Extensions
-
1a. There are no tasks to be undone.
-
1a1. Athletick shows an error message.
Use case ends
-
-
1b. The most recent command cannot be undone.
-
1b1. Athletick shows the most recent command that can be undone and undo
Use case ends.
-
UC7 - Redo a command
Actor: User
MSS
-
User calls for redo
-
Undo command is redone
Use case ends.
Extensions
-
1a. No Redo Command to be redone
-
1a1. Athletick shows an error message.
Use case ends.
-
UC8 - View training and performance records on specific date
Actor: User
MSS
-
User requests to view records on specific date
-
Athletick displays training and performance records on specified date
Use case ends.
Extensions
-
1a. The specified date is invalid.
-
1a1. Athletick shows an error message.
Use case ends.
-
-
1b. The specified date does not contain any records.
-
1b1. Athletick informs the user that the specified date does not contain any records.
Use case ends.
-
UC9 - Navigate to a different date on calendar
Actor: User
MSS
-
User requests jump to a specific month and year.
-
Athletick displays training and performance records on specified date.
Use case ends.
Extensions
-
1a. The specified date is invalid.
-
1a1. Athletick shows an error message.
Use case ends.
-
-
1b. The specified date does not contain any records.
-
1b1. Athletick informs the user that the specified date does not contain any records.
Use case ends.
-
Appendix D: 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 persons 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.
Appendix E: Glossary
- Mainstream OS
-
Windows, Linux, Unix, OS-X
- CLI
-
Command line interface (CLI) is a text-based interface that is used to operate software and operating systems while allowing the user to respond to visual prompts by typing single commands into the interface and receiving a reply in the same way.
- Time-based Sports
-
Examples of time-based sports are swimming and track & field, where performance can be measured in terms of time or distance.
Appendix F: Product Survey
Author: Dominique Ng Wenyi
Pros:
-
Availability of team members for future trainings can be shown
-
Alerts given to user for upcoming trainings or a change in attendance
Cons:
-
Lacks analysis of data with visual aids like charts
-
Lacks an in-built calendar for an overview of schedule
Appendix G: Instructions for Manual Testing
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. |
Launch and Shutdown
-
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.
-
Deleting a person
-
Deleting a person while all persons are listed
-
Prerequisites: List all persons using the
list
command. Multiple persons in the list. -
Test case:
delete -p 1
Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. -
Test case:
delete -p 0
Expected: No person 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).
Expected: Similar to previous.
-
Selecting an athlete
-
Selecting an athlete while all athletes are listed
-
Prerequisites: List all athletes using the
list
command. Multiple athletes in the list. -
Test case:
select 1
Expected: First athlete is selected from the list. Details of the selected athlete shown in the feature box. -
Test case:
select 0
Expected: No person is deleted. Error details shown in result box.
-
Adding/editing an image of an athlete
-
Adding or editing an image of an athlete
-
Prerequisites: Move the image files to be used into the
images
folder. -
Test case:
add n/John Doe p/98765432 e/johnd@example.com g/male a/311, Clementi Ave 2, #02-25 t/backstroke i/john.png
Expected: Athlete is added with the image john.png set as the profile picture. -
Test case:
edit 2 i/john.png
Expected: Athlete’s profile image is set as john.png. -
Test case:
edit 1 i/bobby.png
Expected: Error message : Image file does not exist. Make sure image file is in theimages
folder.
-
Adding a training using athletes present
-
Add a training by indicating athletes present
-
Prerequisites: There must be at least one person in the list. Use the
list
,filter
orfind
commands. -
Test case:
training d/11112019 #/1
Expected: Result box indicates that training is successfully added. A green dot will appear on calendar at the date 11th of November 2019 indicating successful adding of training. Running thecalendar 11112019
command will show that the first person attended training and everyone else will be displayed as absent. -
Test case:
training #/1
Expected: Result box indicates that training is successfully added. A green dot will appear on calendar at today’s date indicating successful adding of training. Running thecalendar
command with today’s date will show that the first person attended training and everyone else will be displayed as absent. -
Test case:
training d/11112019 #/0
Expected: No training added. Error details shown in the result box. -
Other incorrect commands:
training d/1234567890 #/1
,training
Expected: Similar to previous.
-
Adding a training using athletes absent
-
Add a training by indicating athletes absent
-
Prerequisites: There must be at least one person in the list. Use the
list
,filter
orfind
commands. -
Test case:
training -a d/11112019 #/1
Expected: Result box indicates that training is successfully added. A green dot will appear on calendar at the date 11th of November 2019 indicating successful adding of training. Running thecalendar 11112019
command will show that the first person was absent from training and everyone else will be displayed as present. -
Test case:
training -a #/1
Expected: Result box indicates that training is successfully added. A green dot will appear on calendar at today’s date indicating successful adding of training. Running thecalendar
command with today’s date will show that the first person was absent from training and everyone else will be displayed as present. -
Test case:
training -a d/11112019 #/0
Expected: No training added. Error details shown in the result box. -
Other incorrect commands:
training d/1234567890 #/1
,training
Expected: Similar to previous.
-
Editing a training
-
Edit a training attendance
-
Prerequisites: There must exist a training on the input date.
-
Test case:
training d/11112019 #/1
Expected: Result box indicates that training was successfully replaced. Green dot that was previously on the calendar at 11th November 2019 remains there. Running thecalendar 11112019
command shows the new attendance of training. -
Test case:
training d/11112019 #/0
Expected: Training is not replaced. Error details shown in the result box.
-
Deleting a training
-
Delete a training at date
-
Prerequisites: There must exist a training on the input date.
-
Test case:
delete -t d/11112019
Expected: Result box indicates that training was successfully deleted. Green dot that was previously on the calendar at 11th November 2019 disappears. Running thecalendar 11112019
command shows the new attendance of training. -
Test case:
training d/11112019 #/0
Expected: Training is not replaced. Error details shown in the result box.
-
Viewing attendance of one athlete
-
View attendance of one athlete
-
Prerequisites: There must be at least one person in the list. Use the
list
,filter
orfind
commands. -
Test case:
attendance 1
Expected: Result box indicates the attendance of specified athlete. -
Test case:
attendance 0
Expected: Attendance is not shown. Error details shown in the result box. -
Other incorrect attendance commands to try:
attendance
,attendance x
(where x is larger than the list size) {give more}
Expected: Similar to previous.
-
Viewing overall attendance
-
View attendance of all athletes
-
Prerequisites: None.
-
Test case:
view attendance
Expected: Result box indicates the team’s attendance is being displayed. Also, display in the application will show u a list of your athletes and their attendance beside their names. -
Other incorrect view attendance commands to try:
view
,view everyones attendance
(where x is larger than the list size) {give more}
Expected: Error details shown in result box.
-
Viewing the calendar
-
Displaying the calendar for the current month
-
Prerequisites: Currently viewing another feature (e.g. attendance, performance or records).
-
Test case:
view calendar
Expected: Calendar for the current month is displayed in the feature box. The success message "Viewing your calendar" is displayed in the result box. -
Test case:
view f
(any String exceptattendance
,performance
andrecords
)
Expected: Calendar is not displayed. Error details shown in the result box. -
Other incorrect view commands to try:
view
,view x
(where x is an integer). Expected: Similar to previous.
-
Navigating the calendar
-
Displaying the calendar for a specific month and year
-
Test case:
calendar 012019
Expected: Calendar for January 2019 is displayed in the feature box. The success message "Viewing calendar for: January 2019" is displayed in the result box. -
Test case:
calendar 132019
Expected: Invalid date provided, calendar for specified month is not displayed. Error details shown in the result box. -
Test case:
calendar 010000
Expected: Similar to previous. -
Test case:
calendar s
(any String)
Expected: Similar to previous. -
Other incorrect delete commands to try:
calendar x
(where x is any combination of numbers that is not length of 6 or 8) Expected: Similar to previous.
-
Viewing training and performance records
-
Viewing training and performance records recorded on a specific date
-
Test case:
calendar 01012019
Expected: Records for 1st January 2019 are displayed in the feature box. The success message "Viewing details for: 1st January 2019" is displayed in the result box. -
Test case:
calendar 32012019
Expected: Invalid date provided, records for specified date is not displayed. Error details shown in the result box. -
Test case:
calendar 01010000
Expected: Similar to previous. -
Test case:
calendar s
(any String)
Expected: Similar to previous. -
Other incorrect delete commands to try:
calendar x
(where x is any combination of numbers that is not length of 6 or 8) Expected: Similar to previous.
-
Adding an event
-
Adding an event while all events are listed
-
Prerequisites: List all events using the
view performance
command. Multiple events in the list (freestyle 50m
is inside,backstroke 100m
is not). -
Test case:
event backstroke 100m
Expected:backstroke 100m
event is added to the list. Details of the added event shown in the status message. -
Test case:
event freestyle 50m
Expected: No event is added. Error details shown in the status message. -
Other incorrect add commands to try:
add event
,new event
.
Expected: The former will result in an error message for adding a person. The latter will result in a general unknown command error message.
-
Deleting an event
-
Deleting an event while all events are listed
-
Prerequisites: List all events using the
view performance
command. Multiple events in the list (freestyle 50m
is inside,backstroke 100m
is not). -
Test case:
delete -e freestyle 50m
Expected:freestyle 50m
event is deleted from the list. Details of the deleted event shown in the status message. -
Test case:
delete -e backstroke 100m
Expected: No event is deleted. Error details shown in the status message. -
Other incorrect delete commands to try:
delete e
,delete event
.
Expected: Similar to previous.
-
Undoing a previous command
-
Undoing a previous command after user executes
list
command-
Prerequisites: Previous command is
list
. -
Test case:
undo
Expected: Error details shown in the status message. Status bar remains the same. List of people remains the same. -
Other incorrect undo commands to try:
undo x
(where x is any word)
Expected: Similar to previous.
-
Redoing a previous command
-
Redoing a previous command after user executes
undo
command-
Prerequisites: Previous command is
undo
. -
Test case:
redo
Expected:undo
command reversed. Details of the redone command shown in the status message. -
Test case:
redo undo
Expected: Error details shown in status message. Status bar remains the same. List of people remains the same.
-