By: Team AY1920S1-W13-1
Since: Sep 2019
Licence: MIT
- 1. Introduction
- 2. Setting up
- 3. 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 developer guide describes the software architecture and implementation details of the software, ModuleBook. It is intended to be read by developers and software testers for the software.
2. Setting up
Refer to the guide here.
3. Design
3.1. Architecture
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.
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 add CS2103T
.
add CS2103T
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
, ModuleListPanel
, StatusBarFooter
, HomeViewPanel
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 theModuleBookParser
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 module). -
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("add CS2103T")
API call.
Add CS2103T
Command
The lifeline for AddCommandParser 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 ModuleBook data.
-
exposes an unmodifiable
ObservableList<Module>
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.
3.5. Storage component
API : Storage.java
The Storage
component,
-
can save
UserPref
objects in json format and read it back. -
can save the
TrackedModule
data in json format and read it back. -
can read the
ArchivedModule
data from json format.
3.6. Common classes
Classes used by multiple components are in the seedu.module.commons
package.
4. Implementation
This section describes some noteworthy details on how certain features are implemented.
4.1. Module View Feature
The module view feature allows users to view a module to access extra information about the module. The user can view (and unview) a module using the view
(and back
) commands.
4.1.1. Implementation
The module view feature is facilitated by displayedModule
in ModelManager
. The following describes how the displayedModule
is modified and read to the Ui
.
-
The user enters a view command in the
Ui
. -
LogicManager
parses the user input, constructs and executes theViewCommand
. -
The
ViewCommand
attempts to find the matching module from the list of Tracked Modules, else it attempts to find the matching module from the list of Archived Modules, else it throws an exception. -
The
ViewCommand
sets thedisplayedModule
in theModel
and returns theCommandResult
to theLogicManager
. -
The
LogicManager
returns theCommandResult
to theUi
. -
The
Ui
gets thedisplayedModule
fromLogicManager
and updates the Ui to display the module.
The following sequence diagram shows how the module view feature is executed.
The BackCommand mostly follows the same sequence as described above, except that it does not need to find any module, and sets the displayed module to null .
|
The following activity diagram describes the process of finding a matching module to display.
4.1.2. Design Considerations
Updating the Ui
Current Implementation: New field in the CommandResult
that the Ui will check to determine if it needs to update.
Pros:
-
Simple and easy to control what command updates the Ui.
Cons:
-
More difficult to maintain over the course of the project. New Ui elements require new fields to update the Ui.
Alternate Implementation: Every command updates the Ui.
Pros:
-
Maintainance free.
Cons:
-
Potentially inefficient.
-
Possible side effects from certain commands.
4.2. [Proposed] Marking modules as completed, ongoing or planned
Users can mark modules as
4.2.1. Implementation
The tracked module will have 2 new fields: moduleStatus
and semesterTimestamp
.
The moduleStatus
will be an enumeration of:
-
completed , -
ongoing and -
planned .
The semesterTimestamp
will be a combination of:
-
an academic year
-
In NUS, the academic year representation is prefixed with "AY", followed by the last 2 digits of the starting year, and the last 2 digits of the ending year
-
e.g. AY1920, AY2021
-
-
a semester
-
In NUS, there are a total of 4 semesters. Semester 1, Semester 2, Special Term 1 (ST1) and Special Term 2 (ST2).
-
e.g. 1, 2, ST1, ST2
-
The user will be free to modify the moduleStatus
and the semesterTimestamp
. The following class diagram will illustrate the above implementation.
4.2.2. Possible Extensions
With the new data, users may be able to easier manage their tracked modules and gleam useful information.
-
Completed modules will be hidden from the module list, but still viewable through alistall
command (proposed command) and accessible through theview
command. -
Completed modules andongoing modules can be used to determine if a user fulfil the requirements for theirplanned modules .
4.3. Search filtering feature
4.3.1. Implementation
The search filtering feature Uses different categories of predicates
to narrow down the search space of the archived module list. The user is able to able to combine different categories
of search to find modules that passes all the user defined filters. This can be achieved through the use of Predicate
which can be chained with additional predicates and applied to a FilteredList
. This requires additional predicate classes that searches their individual fields
for the keywords.:
-
ModuleCodeContainsKeywordsPredicate
— Tests that amodule
module code matches any of the keywords given. -
TitleContainsKeywordsPredicate
— Tests that amodule
title contains all of the keywords given. -
DescriptionContainsKeywordsPredicate
— Tests that amodule
description contains all of the keywords given. -
PrerequisiteContainsKeywordsPredicate
— Tests that amodule
prerequisites matches any of the keywords given. -
PreclusionContainsKeywordsPredicate
— Tests that amodule
preclusions matches any of the keywords given. -
SemesterContainsKeywordsPredicate
— Tests that amodule
semester matches any of the keywords given.
As shown in the figure above, predicate classes are created in the FindCommandParser, the list of predicates is used to construct a find command. Note that only DescriptionContainsKeywordsPredicate and TitleContainsKeywordsPredicate depends on LevenshteinDistanceChecker, the rest of the predicates do not depend on it.
The figure above shows how each predicate checks for the keyword. Do note that DescriptionContainsKeywordsPredicate
and TitleContainsKeywordsPredicate
requires their specified field to contain all of the keywords, while the rest of the
predicates returns true as long as their field contains at least one of the keyword.
The user is able to use any combination of filters and the order of input should not matter. Examples of valid find commands:
The following sequence diagram shows how the find operation wold work:
The lifeline for FindCommand should end at the destroy marker (X) but due to a limitation of PlantUML, the lifeline reaches the end of diagram.
|
As represented in the figure above, when a FindCommandParser
is constructed by ModuleBookParser#parseCommand
, the FindCommandParser
would construct a list
of Predicate<module>
based on the parsed arguments, which is used to construct a FindCommand
.
During the execution of FindCommand#execute()
, each predicate is chained and applied to the FilteredList
.
Finally, a FilteredList
of Modules
that passes all of the filters will be displayed.
4.3.2. Design Considerations
Aspect: Requirements.
-
Module field requirements: Information from the
archivedModules.json
would have to be abstracted out as individual fields in theArchivedModule
object.-
pros: Added fields can be used for future developments.
-
cons: Can potentially slow down
Module
construction and operations due to increased size for eachModule
object.
-
Aspect: Fuzzy search.
-
Search with spelling mistake tolerance: Due to the potential of spelling mistakes within fields such as the module and module discription which does not rely on module codes, searching these fields can accept mistakes with a degree of 2 Levenshtein Distance from any of the original intended word.
-
pros: Much more robust searching potential.
-
cons: Will slow down the search.
-
Aspect: Incremental development.
-
Adding new search filters: Developing and integrating new filters.
-
pros: Filters can be developed independently and incrementally, filters can be integrated based on priority.
-
pros: Can be further adapted to search fields from
Deadline
andLinks
.
-
4.4. Deadline Management Feature
As a module management system, one of the important features will be the management of deadlines for each modules.
This section will elaborate the current implementation and design considerations of deadline management feature.
4.4.1. Current implementation
The deadline management feature supports the following main operations.
-
add
- adds a new deadline task to the respective module. -
edit
- edits the description or date and time of deadline task. -
done
- marks a deadline task as done. -
doneAll
- marks all the deadline tasks as done. -
inProgress
- marks a deadline task as inProgress. -
undone
- marks a deadline task as undone -
delete
- deletes an existing task from the deadline list. -
deleteAll
- deletes the entire deadline list from a module.
The following activity diagram summarises what happened when a user executes the AddDeadlineCommand:
The format to add deadline command is as follows:
deadline 2 a/add d/description t/dateAndTime p/priority
The add deadline mechanism is facilitated by AddDeadlineCommand
and AddDeadlineCommandParser
.
It takes in the following input from the user: MODULE_LIST_NUMBER
, DESCRIPTION
, DATE_AND_TIME
and
PRIORITY
which will construct a Deadline object to be added to the deadline list.
Given below is an example usage scenario of how add deadline mechanism behaves at each step.
Step 1. The user executes:
deadline 2 a/add d/do homework t/2/12/2019 1645 p/MEDIUM
Step 2. LogicManager
would use ModuleBookParser#parseCommand()
to parse input from the user.
Step 3. ModuleBookParser
would determine which command is being used and creates the respective parser.
In this case, DeadlineCommandParser
is being created from the COMMAND.WORD: deadline
and
the user’s input would be passed in as a parameter.
Step 4. DeadlineCommandParser
would then determine which action is being used and creates the respective parser.
In this case, AddDeadlineCommandParser
is created and user’s input would be parsed.
Step 5. AddDeadlineCommandParser
would do a validation check on the user’s input before creating
and returning a AddDeadlineCommand
with index
and Deadline
as its attributes. index
represents
the TrackedModule
list index (i.e 2) which the Deadline
object will be added to.
Step 6. LogicManager
would execute AddDeadlineCommand#execute()
,
checks whether there is an existing module,
then adds to the TrackedModule
.
Step 7. AddDeadlineCommand
would return a CommandResult
to the LogicManager
.
The following sequence diagram illustrates how the add deadline operation works:
4.4.2. Design Considerations
Aspect: Data Structure used to support add command
-
Alternative 1(Current choice) : Use of
ArrayList
to store deadline tasks in aTrackedModule
.-
Pros: Commands (eg. edit, sort, delete) can be easily supported by a list operations.
-
Pros: Ensures that only one deadline list is maintained for each TrackedModule.
-
Cons: More difficult to maintain over the course of the project. New commands(eg. done, priority) need to edit and maintain the list constantly.
-
Cons: Duplicate deadline tasks harder to identify.
-
-
Alternative 2 : Use a
HashSet
to store deadline tasks in aTrackedModule
.-
Pros: Duplicate deadline tasks can be identified easily.
-
Cons: Not easy to identify tasks using index.
-
4.5. 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.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 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.6. Configuration
Certain properties of the application can be controlled (e.g user prefs file location, logging level) through the configuration file (default: config.json
).
4.7. Link Management Feature
The link management feature allows users to add and manage a set of website links that will be associated with a given module.
4.7.1. Overview of link feature
Implementation
Our application currently supports adding and managing of links specific to certain modules.
The link management feature is primarily facilitated by the following classes:
-
Link
- represents a link object -
TrackedModule
- represents a module that was tracked. Stores theLink
objects related to it. -
LinkCommand
- embodies thelink
command input given by the user and contains the necessary changes that will be made to theTrackedModule
object. -
LinkCommandParser
- parses user input related tolink
commands and returns the correspondingLinkCommand
to be executed.
Each link
object is stored in an ArrayList<Link>
, which in turn is stored in its corresponding TrackedModule
.
In summary, the class diagram of how Link
is implemented is shown as:
The link feature currently recognizes and supports add, delete, edit and launch commands.
Link commands are parsed through the LinkCommandParser
class, which in turn calls the respective XYZLinkCommandParser
class (i.e. AddLinkCommandParser
, EditLinkCommandParser
).
The XYZLinkCommandParser
class parses and returns a corresponding XYZLinkCommand
class, which calls execute()
and the TrackedModule
will be updated accordingly if the execution was successful.
The following activity diagram summarizes what happens when the link command is entered and executed:
An example usage scenario of an add link operation is given below and the behavior of the link management feature is shown.
-
The user launches the application with an existing save file.
ModuleBook
is initialized with existingTrackedModule
. -
The user inputs
link add n/LINK_NAME l/LINK_URL
to add a link with nameLINK_NAME
, linked toLINK_URL
to theTrackedModule
with the correspondingMODULE_INDEX
. -
LogicManager
receives user input and parses it usingModuleBookParser#parseCommand()
.ModuleBookParser
reads theCOMMAND_WORD
and identifies the input as aLink
related command and passes the input toLinkCommandParser
. -
LinkCommandParser
determines theadd
action required. It then proceeds to pass the relevant input toAddLinkCommandParser
. -
AddLinkCommandParser
checks for the validity ofLINK_URL
given by the user and creates the relevantLink
andAddLinkCommand
objects. -
AddLinkCommand
callsModel#getDisplayedModule()
to find the required module. If it does not exist or is not currently tracked,AddLinkCommand
throws aCommandException
. Otherwise, it then proceeds to callTrackedModule#hasLinkTitle(LINK_NAME)
to check for an existingLink
object with the sameLINK_NAME
. -
If such a
Link
object exists,AddLinkCommand
aborts and throws aCommandException
. Otherwise, the createdLink
will be added to the specifiedTrackedModule
. -
If the operation is successful, a
CommandResult
with the success message will be returned.
4.7.2. Design Considerations
Aspect: Data structure used for link management
-
Alternative 1: All
TrackedModule
maintain aArrayList<Link>
. AddingLink
objects will add to thisArrayList
.-
Pros: Easy to implement and edit for beginner programmers.
-
Cons: Accessing and editing existing
Link
might be less efficient. If number ofLink
objects maintained increases,ArrayList
may not be optimal.
-
-
Alternative 2: Use
HashSet<Link>
to maintainLink
in eachTrackedModule
-
Pros: Reduces access time, since
Link
objects can be obtained by givingLINK_TITLE
, rather than searching the list linearly for a matching object. -
Cons: Difficult to add features. Future implmentations may add a
Priority
feature toLink
objects.HashSet
does not support any form of sorting and thus may pose a problem.
-
-
Solution (current implementation): Adopt alternative 1. Since from a user standpoint, the number of links added to any module should not be too large to affect performance of application.
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:
-
is a student of National University of Singapore (NUS)
-
prefer desktop apps over web apps
-
can type fast
-
prefers typing over mouse input
-
is reasonably comfortable using CLI apps
Value proposition: manage modules faster and with less hassle than the traditional web apps deployed by the institution
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… |
---|---|---|---|
|
new user |
see usage instructions |
refer to instructions when I forget how to use the App |
|
user |
track a module I’m currently taking |
|
|
user |
untrack a module |
remove entries that I no longer need |
|
user |
find a module |
locate details of modules that NUS provides |
|
curious student |
view a module’s details |
check out if I want to take the module |
|
busy student |
add and manage deadlines |
keep track of my assignments and tasks |
|
organized student |
add and manage hyperlinks |
keep track of online resources and websites that the module uses |
|
student |
catalog past modules |
know what modules I have taken, and access the content if needed |
|
graduating student |
check what modules I need to complete |
|
|
computing student |
plan my focus area modules |
choose a specialization |
|
busy student |
prioritize certain modules (and their deadlines) |
manage my time better |
|
organized student |
add and manage files |
keep track of files related to a module |
|
organized student |
add notes to a module |
keep track of certain information about a module |
|
hardworking student |
access past exam papers |
download them without too much hassle |
|
organized student |
track my grades |
know roughly how well I’m doing in the module |
|
competitive student |
calculate my GPA |
|
|
new student |
schedule my modules |
plan how to approach my future focus areas |
|
student |
generate a sample module planner |
plan my modules |
Appendix C: Use Cases
(For all use cases below, the System is the ModuleBook
and the Actor is the user
, unless specified otherwise)
Use case: Find and Track a Module
MSS
-
User requests to find a module with incomplete keyword (e.g. 'CS2')
-
ModuleBook shows a list of modules matching the keyword (e.g. 'CS2030, CS2040, CS2100, CS2101, etc.')
-
User requests to track a module
-
ModuleBook tracks the module and displays to the user that the module is now tracked.
Use case ends.
Use case: Add a deadline for a tracked module
MSS
-
User requests to view the specific tracked module
-
ModuleBook displays the module details
-
User requests to add a deadline
-
ModuleBook adds the deadline
Use case ends.
Extensions
-
2a. The module is not currently tracked
-
2a1. User requests to track the module
-
2a2. The module is now tracked
Use case resumes at step 3
-
-
3a. ModuleBook requests for a description
-
3a1. User provides a description
-
3a2. ModuleBook requests for a datetime
-
3a3. User provides a datetime
Use case resumes at step 4.
-
{More to be added}
Appendix D: Non Functional Requirements
-
Should work on any mainstream OS as long as it has Java
11
or above installed. -
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.
-
Should be able to track and manage about 60 modules without unreasonable lag (as this is roughly more than the number of modules a typical student is expected to complete at NUS).
Appendix E: Glossary
E.1. Common Application terms
Home view - The state of the application that displays the home page in the main panel.
Module view - The state of the application that displays the specified module in the main panel.
E.2. Common Module terms
Archived - A module that the institution provides. Can be viewed and tracked. It is indicated by a gray vertical bar on the module list.
Tracked - A module that is tracked. References an archived module. Can be viewed and untracked. It is indicated by a green vertical bar on the module list.
Appendix F: Product Survey
LumiNUS
Pros:
-
Good deadline system
-
Working file management system
Cons:
-
A lot of GUI navigation involved
-
Cannot add user-generated deadlines
-
Cannot view past module details or content
NUSMods
Pros:
-
Easy to use and powerful module search feature
-
Modules come with schedules for tutorials, lectures, etc
Cons:
-
Not applicable for managing modules (such as deadlines, grades)
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. |
G.1. 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.
-
G.2. Deleting a module
-
Deleting a module while all modules are listed
-
Prerequisites: List all modules using the
list
command. Multiple modules in the list. -
Test case:
delete cs2103t
Expected: Module with module code cs2103t 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 INVALID_MODULE_CODE
Expected: No module is deleted. Error details shown in the status message. Status bar remains the same.
-