Skip to content

Commit

Permalink
Merge pull request #115 from emmannyyy/Developer-Guide
Browse files Browse the repository at this point in the history
Updates Developer guide
  • Loading branch information
jian7490 authored Oct 22, 2024
2 parents 824e879 + 07a190f commit 7da33df
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 47 deletions.
76 changes: 63 additions & 13 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@
--------------------------------------------------------------------------------------------------------------------

## **Acknowledgements**
The following table acknowledges numerous 3rd party libraries, API and documentation that were used in the development of TAchy.

_{ list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well }_
| Name | Description |
|-----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
| [AddressBook-Level 3 (AB-3)](https://se-education.org/addressbook-level3/) | TAchy is a brownfield project adapted from AB-3, which was created by the [SE-EDU initiative](https://se-education.org). |
| [Jackson](https://github.com/FasterXML/jackson) | Used for parsing JSON files. |
| [Gradle](https://gradle.org/) | Used for build automation |
| [JavaFX](https://openjfx.io) | Used in rendering the GUI. |
| [JUnit5](https://junit.org/junit5/) | Used for testing the codebase. |
| [Oracle Java Docs](https://docs.oracle.com/en/java/javase/11/docs/api/index.html) | Used for understanding the default Java API |

--------------------------------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -50,7 +58,7 @@ The bulk of the app's work is done by the following four components:

**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`.
The *Sequence Diagram* below shows how the components interact with each other for the scenario where the user issues the command `delete_student 1`.

<puml src="diagrams/ArchitectureSequenceDiagram.puml" width="574" />

Expand All @@ -71,7 +79,7 @@ The **API** of this component is specified in [`Ui.java`](https://github.com/se-

<puml src="diagrams/UiClassDiagram.puml" alt="Structure of the UI Component"/>

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 which captures the commonalities between classes that represent parts of the visible GUI.
The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `StudentListPanel`, `StatusBarFooter` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class which captures the commonalities between classes that represent parts of the visible GUI.

The `UI` component uses the 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`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/ui/MainWindow.java) is specified in [`MainWindow.fxml`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/resources/view/MainWindow.fxml)

Expand All @@ -80,7 +88,7 @@ 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.
* keeps a reference to the `Logic` component, because the `UI` relies on the `Logic` to execute commands.
* depends on some classes in the `Model` component, as it displays `Person` object residing in the `Model`.
* depends on some classes in the `Model` component, as it displays `Student` object residing in the `Model`.

### Logic component

Expand All @@ -90,9 +98,9 @@ Here's a (partial) class diagram of the `Logic` component:

<puml src="diagrams/LogicClassDiagram.puml" width="550"/>

The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete 1")` API call as an example.
The sequence diagram below illustrates the interactions within the `Logic` component, taking `execute("delete_student 1")` API call as an example.

<puml src="diagrams/DeleteSequenceDiagram.puml" alt="Interactions Inside the Logic Component for the `delete 1` Command" />
<puml src="diagrams/DeleteSequenceDiagram.puml" alt="Interactions Inside the Logic Component for the `delete_student 1` Command" />

<box type="info" seamless>

Expand All @@ -102,10 +110,10 @@ The sequence diagram below illustrates the interactions within the `Logic` compo
How the `Logic` component works:

1. When `Logic` is called upon to execute a command, it is passed to an `AddressBookParser` object which in turn creates a parser that matches the command (e.g., `DeleteCommandParser`) and uses it to parse the command.
1. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
1. The command can communicate with the `Model` when it is executed (e.g. to delete a student).<br>
2. This results in a `Command` object (more precisely, an object of one of its subclasses e.g., `DeleteCommand`) which is executed by the `LogicManager`.
3. The command can communicate with the `Model` when it is executed (e.g. to delete a student).<br>
Note that although this is shown as a single step in the diagram above (for simplicity), in the code it can take several interactions (between the command object and the `Model`) to achieve.
1. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`.
4. The result of the command execution is encapsulated as a `CommandResult` object which is returned back from `Logic`.

Here are the other classes in `Logic` (omitted from the class diagram above) that are used for parsing a user command:

Expand All @@ -123,14 +131,14 @@ How the parsing works:

The `Model` component,

* stores the address book data i.e., all `Person` objects (which are contained in a `UniquePersonList` object).
* stores the currently 'selected' `Person` objects (e.g., results of a search query) as a separate _filtered_ list which is exposed to outsiders as 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.
* stores the address book data i.e., all `Student` objects (which are contained in a `UniqueStudentList` object).
* stores the currently 'selected' `Student` objects (e.g., results of a search query) as a separate _filtered_ list which is exposed to outsiders as an unmodifiable `ObservableList<Student>` 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.
* stores a `UserPref` object that represents the user’s preferences. This is exposed to the outside as a `ReadOnlyUserPref` objects.
* does not depend on any of the other three components (as the `Model` represents data entities of the domain, they should make sense on their own without depending on other components)

<box type="info" seamless>

**Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Person` references. This allows `AddressBook` to only require one `Tag` object per unique tag, instead of each `Person` needing their own `Tag` objects.<br>
**Note:** An alternative (arguably, a more OOP) model is given below. It has a `Tag` list in the `AddressBook`, which `Student` references. This allows `AddressBook` to only require one `Tag` object per unique tag, instead of each `Student` needing their own `Tag` objects.<br>

<puml src="diagrams/BetterModelClassDiagram.puml" width="450" />

Expand All @@ -156,7 +164,49 @@ Classes used by multiple components are in the `seedu.address.commons` package.

## **Implementation**

This section describes some noteworthy details on how certain features are implemented.

### Introduction
This section of the developer Guide covers how the features are implemented and executed.

### Features Overview
Listed below are the implemented features, and a brief description of what they do.
* **Adding a new Assignment**: Adds a new Assignment for a particular student
* **Grading an existing Assignment**: Grades an existing assignment belonging to an existing student
* **Deleting an existing Assignment**: Deletes an existing assignment belonging to an existing student
* **Viewing a student's details**: Displays students details along with the assignments associated with the student

## Adding a new Assignment
This `add_assignment` command is a feature that allows the user to create a new assignment, based on the student's index. The assignment must have an alphanumeric `Name`, and a valid `Max Score`.

#### Design Considerations:
Previously, AB3 had a single command word for the `add` commands. As TAchy is a brownfield project, additional objects are now allowed to be instantiated via the `add` commmand.
In particular, TAchy has 2 features that "add" items to the app. Firstly, there is an `add_student` feature, and also an `add_assignment` feature.

**Aspect: How to distinguish between the different 'add' commands:**
* Alternative 1 (current choice): Distinguish command word, and thus allow only 1 type of object to be created at a time.
* Pros: Easy to implement, and less prone to Users making errors in command format
* Cons: User will only be able to add either students or assignments, one at a time

* Alternative 2: Allow multiple objects to be created concurrently.
* Pros: Allows adept users to create new objects in the app more quickly
* Cons: Difficult to implement, and users are prone to making more mistakes in supplying the valid parameters used.


#### Implementation
* LogicManager executes the command "add_assignment".
* LogicManager parses the command via AddressBookParser.
* AddressBookParser creates and delegates parsing to AddAssignmentCommandParser.
* AddAssignmentCommandParser creates an AddAssignmentCommand object.
* AddAssignmentCommand is returned to AddAssignmentCommandParser and back to AddressBookParser.
* LogicManager then executes AddAssignmentCommand, which interacts with the Model.
* AddAssignmentCommand creates a CommandResult object.
* CommandResult is returned to AddAssignmentCommand, which returns the result to LogicManager.
* The sequence concludes with the return to the caller from LogicManager.
* This describes the flow of command execution, parsing, and interaction with the model.

#### Example invocation sequence for AddAssignmentCommand
<puml src="diagrams/AddAssignmentSequenceDiagram.puml" alt="Interactions Inside the Logic Component for the `add_assignment` Command" />


### \[Proposed\] Undo/redo feature

Expand Down
68 changes: 68 additions & 0 deletions docs/diagrams/AddAssignmentSequenceDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
@startuml
!include style.puml
skinparam ArrowFontStyle plain

box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
participant ":AddAssignmentCommandParser" as AddAssignmentCommandParser LOGIC_COLOR
participant "a:AddAssignmentCommand" as AddAssignmentCommand LOGIC_COLOR
participant "r:CommandResult" as CommandResult LOGIC_COLOR
end box

box Model MODEL_COLOR_T1
participant "m:Model" as Model MODEL_COLOR
end box

[-> LogicManager : execute("add_assignment")
activate LogicManager

LogicManager -> AddressBookParser : parseCommand("add_assignment ")
activate AddressBookParser

create AddAssignmentCommandParser
AddressBookParser -> AddAssignmentCommandParser
activate AddAssignmentCommandParser

AddAssignmentCommandParser --> AddressBookParser
deactivate AddAssignmentCommandParser

AddressBookParser -> AddAssignmentCommandParser : parse()
activate AddAssignmentCommandParser


create AddAssignmentCommand
AddAssignmentCommandParser -> AddAssignmentCommand : AddAssignmentCommand()
activate AddAssignmentCommand

AddAssignmentCommand --> AddAssignmentCommandParser :
deactivate AddAssignmentCommand

AddAssignmentCommandParser --> AddressBookParser : d
deactivate AddAssignmentCommandParser
'Hidden arrow to destroy the marker below the end of the activation bar
AddAssignmentCommandParser -[hidden]-> AddressBookParser
destroy AddAssignmentCommandParser

AddressBookParser --> LogicManager : d
deactivate AddressBookParser

LogicManager -> AddAssignmentCommand : execute(m)
activate AddAssignmentCommand

AddAssignmentCommand -> Model :
Model --> AddAssignmentCommand

create CommandResult
AddAssignmentCommand -> CommandResult
activate CommandResult

CommandResult --> AddAssignmentCommand
deactivate CommandResult

AddAssignmentCommand --> LogicManager : r
deactivate AddAssignmentCommand

[<-- LogicManager
deactivate LogicManager
@enduml
6 changes: 3 additions & 3 deletions docs/diagrams/ArchitectureSequenceDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ Participant ":Logic" as logic LOGIC_COLOR
Participant ":Model" as model MODEL_COLOR
Participant ":Storage" as storage STORAGE_COLOR

user -[USER_COLOR]> ui : "delete 1"
user -[USER_COLOR]> ui : "delete_student 1"
activate ui UI_COLOR

ui -[UI_COLOR]> logic : execute("delete 1")
ui -[UI_COLOR]> logic : execute("delete_student 1")
activate logic LOGIC_COLOR

logic -[LOGIC_COLOR]> model : deletePerson(p)
logic -[LOGIC_COLOR]> model : delete(p)
activate model MODEL_COLOR

model -[MODEL_COLOR]-> logic
Expand Down
18 changes: 9 additions & 9 deletions docs/diagrams/BetterModelClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ skinparam arrowThickness 1.1
skinparam arrowColor MODEL_COLOR
skinparam classBackgroundColor MODEL_COLOR

AddressBook *-right-> "1" UniquePersonList
AddressBook *-right-> "1" UniqueStudentList
AddressBook *-right-> "1" UniqueTagList
UniqueTagList -[hidden]down- UniquePersonList
UniqueTagList -[hidden]down- UniquePersonList
UniqueTagList -[hidden]down- UniqueStudentList
UniqueTagList -[hidden]down- UniqueStudentList

UniqueTagList -right-> "*" Tag
UniquePersonList -right-> Person
UniqueStudentList -right-> Student

Person -up-> "*" Tag
Student -up-> "*" Tag

Person *--> Name
Person *--> Phone
Person *--> Email
Person *--> Address
Student *--> Name
Student *--> Phone
Student *--> Email
Student *--> "*" Assignment
@enduml
6 changes: 3 additions & 3 deletions docs/diagrams/DeleteSequenceDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ box Model MODEL_COLOR_T1
participant "m:Model" as Model MODEL_COLOR
end box

[-> LogicManager : execute("delete 1")
[-> LogicManager : execute("delete_student 1")
activate LogicManager

LogicManager -> AddressBookParser : parseCommand("delete 1")
LogicManager -> AddressBookParser : parseCommand("delete_student 1")
activate AddressBookParser

create DeleteCommandParser
Expand Down Expand Up @@ -49,7 +49,7 @@ deactivate AddressBookParser
LogicManager -> DeleteCommand : execute(m)
activate DeleteCommand

DeleteCommand -> Model : deletePerson(1)
DeleteCommand -> Model : deleteStudent(1)
activate Model

Model --> DeleteCommand
Expand Down
30 changes: 14 additions & 16 deletions docs/diagrams/ModelClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Class AddressBook
Class ModelManager
Class UserPrefs

Class UniquePersonList
Class Person
Class Address
Class UniqueStudentList
Class Student
Class Assignment
Class Email
Class Name
Class Phone
Expand All @@ -35,20 +35,18 @@ ModelManager -left-> "1" AddressBook
ModelManager -right-> "1" UserPrefs
UserPrefs .up.|> ReadOnlyUserPrefs

AddressBook *--> "1" UniquePersonList
UniquePersonList --> "~* all" Person
Person *--> Name
Person *--> Phone
Person *--> Email
Person *--> Address
Person *--> "*" Tag
AddressBook *--> "1" UniqueStudentList
UniqueStudentList --> "~* all" Student
Student *--> Name
Student *--> Phone
Student *--> "*" Assignment
Student *--> "*" Tag
Student *--> Email

Person -[hidden]up--> I
UniquePersonList -[hidden]right-> I
Student -[hidden]up--> I
UniqueStudentList -[hidden]right-> I

Name -[hidden]right-> Phone
Phone -[hidden]right-> Address
Address -[hidden]right-> Email

ModelManager --> "~* filtered" Person

ModelManager --> "~* filtered" Student
@enduml
8 changes: 5 additions & 3 deletions docs/diagrams/StorageClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ package "AddressBook Storage" #F4F6F6{
Class "<<interface>>\nAddressBookStorage" as AddressBookStorage
Class JsonAddressBookStorage
Class JsonSerializableAddressBook
Class JsonAdaptedPerson
Class JsonAdaptedStudent
Class JsonAdaptedTag
Class JsonAdaptedAssignment
}

}
Expand All @@ -37,7 +38,8 @@ Storage -right-|> AddressBookStorage
JsonUserPrefsStorage .up.|> UserPrefsStorage
JsonAddressBookStorage .up.|> AddressBookStorage
JsonAddressBookStorage ..> JsonSerializableAddressBook
JsonSerializableAddressBook --> "*" JsonAdaptedPerson
JsonAdaptedPerson --> "*" JsonAdaptedTag
JsonSerializableAddressBook --> "*" JsonAdaptedStudent
JsonAdaptedStudent --> "*" JsonAdaptedTag
JsonAdaptedStudent --> "*" JsonAdaptedAssignment

@enduml

0 comments on commit 7da33df

Please sign in to comment.