Skip to content

Commit

Permalink
Merge pull request #186 from ljy0422/UpdateDGUML
Browse files Browse the repository at this point in the history
Update DG UML
  • Loading branch information
ChuaZenKhoon authored Apr 15, 2024
2 parents 46133f8 + 8a795df commit 7dbcce8
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 20 deletions.
22 changes: 8 additions & 14 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,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 `+ /name Tan Ah Gao /id chihuahua69 /hp 999 /tag finance`.

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

Expand Down Expand Up @@ -90,7 +90,7 @@ 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("- id abc123")` API call as an example.

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

Expand All @@ -101,7 +101,8 @@ 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. When `Logic` is called upon to execute a command, it is first passed to an `AccountManagerParser` object which in turn creates a parser that matches the command (e.g., `LoginCommandParser`) and uses it to parse the command.
1. If the parsing result returned by `AccountManagerParser` is null, the command is then 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 person).<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.
Expand All @@ -112,6 +113,7 @@ Here are the other classes in `Logic` (omitted from the class diagram above) tha
<puml src="diagrams/ParserClasses.puml" width="600"/>

How the parsing works:
* When called upon to parse a user command, the `AccountManagerParser` class creates an `XYZCommandParser` (`XYZ` is a placeholder for the specific command name e.g., `LoginCommandParser`) which uses the other classes shown above to parse the user command and create a `XYZCommand` object (e.g., `LoginCommand`) which the `AccountManagerParser` returns back as a `Command` object.
* When called upon to parse a user command, the `AddressBookParser` class creates an `XYZCommandParser` (`XYZ` is a placeholder for the specific command name e.g., `AddCommandParser`) which uses the other classes shown above to parse the user command and create a `XYZCommand` object (e.g., `AddCommand`) which the `AddressBookParser` returns back as a `Command` object.
* All `XYZCommandParser` classes (e.g., `AddCommandParser`, `DeleteCommandParser`, ...) inherit from the `Parser` interface so that they can be treated similarly where possible e.g, during testing.

Expand All @@ -124,28 +126,20 @@ 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 tag data i.e., all `Tag` objects (which are contained in a `TagList` 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 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>

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

</box>


### Storage component

**API** : [`Storage.java`](https://github.com/se-edu/addressbook-level3/tree/master/src/main/java/seedu/address/storage/Storage.java)

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

The `Storage` component,
* can save both address book data and user preference data in JSON format, and read them back into corresponding objects.
* inherits from both `AddressBookStorage` and `UserPrefStorage`, which means it can be treated as either one (if only the functionality of only one is needed).
* can save both address book data, user preference data and tag list data in JSON format, and read them back into corresponding objects.
* inherits from `AddressBookStorage`, `UserPrefStorage` and `TagListStorage`, which means it can be treated as either one (if only the functionality of only one is needed).
* depends on some classes in the `Model` component (because the `Storage` component's job is to save/retrieve objects that belong to the `Model`)

### Common classes
Expand Down
4 changes: 2 additions & 2 deletions docs/diagrams/ArchitectureSequenceDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Participant ":Logic" as logic LOGIC_COLOR
Participant ":Model" as model MODEL_COLOR
Participant ":Storage" as storage STORAGE_COLOR

user -[USER_COLOR]> ui : "+ /name Tan Ah Gao /id chihuahua69 /hp 999"
user -[USER_COLOR]> ui : "+ /name Tan Ah Gao /id chihuahua69 /hp 999 /tag finance"
activate ui UI_COLOR

ui -[UI_COLOR]> logic : execute("+ /name Tan Ah Gao /id chihuahua69 /hp 999")
ui -[UI_COLOR]> logic : execute("+ /name Tan Ah Gao /id chihuahua69 /hp 999 /tag finance")
activate logic LOGIC_COLOR

logic -[LOGIC_COLOR]> model : addPerson(p)
Expand Down
8 changes: 8 additions & 0 deletions docs/diagrams/ComponentManagers.puml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,21 @@ Class "<<interface>>\nStorage" as Storage
Class StorageManager
}

package AccoutManager as AccoutManagerPackage {
Class AccountManager
}

Class HiddenOutside #FFFFFF
HiddenOutside ..> Logic

LogicManager .up.|> Logic

ModelManager .up.|> Model
StorageManager .up.|> Storage


LogicManager --> Model
LogicManager --> Storage

AccountManager <--> LogicManager
@enduml
7 changes: 7 additions & 0 deletions docs/diagrams/DeleteSequenceDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ skinparam ArrowFontStyle plain

box Logic LOGIC_COLOR_T1
participant ":LogicManager" as LogicManager LOGIC_COLOR
participant ":AccountManagerParser" as AccountManagerParser LOGIC_COLOR
participant ":AddressBookParser" as AddressBookParser LOGIC_COLOR
participant ":DeleteCommandParser" as DeleteCommandParser LOGIC_COLOR
participant "id:Id" as Id LOGIC_COLOR
Expand All @@ -18,6 +19,12 @@ end box
[-> LogicManager : execute("- /id abc123")
activate LogicManager

LogicManager -> AccountManagerParser : parseCommand("- /id abc123")
activate AccountManagerParser

AccountManagerParser --> LogicManager : null
deactivate AccountManagerParser

LogicManager -> AddressBookParser : parseCommand("- /id abc123")
activate AddressBookParser

Expand Down
9 changes: 8 additions & 1 deletion docs/diagrams/LogicClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,26 @@ package Model {
Class HiddenModel #FFFFFF
}

package AccountManager {

}

package Storage {
}

Class HiddenOutside #FFFFFF
HiddenOutside ..> Logic

LogicManager .right.|> Logic
LogicManager -right->"1" ParserClasses
LogicManager -right->"2" ParserClasses
LogicManager -right->"1" AccountManager
ParserClasses ..> XYZCommand : <<create>>

XYZCommand -up-|> Command
LogicManager .left.> Command : <<call>>

AccountManager -> LogicManager

LogicManager --> Model
LogicManager --> Storage
Storage --[hidden] Model
Expand Down
9 changes: 8 additions & 1 deletion docs/diagrams/ModelClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ Class "<<interface>>\nModel" as Model
Class AddressBook
Class ModelManager
Class UserPrefs
Class TagList

Class UniquePersonList
Class Person
'Class Address
'Class Email
Class Name
Class Phone
'Class Tag
Class Tag
Class ID

Class I #FFFFFF
Expand All @@ -41,6 +42,7 @@ UniquePersonList --> "~* all" Person
Person *--> Name
Person *--> ID
Person *--> Phone
Person *--> Tag

Person -[hidden]up--> I
UniquePersonList -[hidden]right-> I
Expand All @@ -49,4 +51,9 @@ Name -[hidden]right-> ID
ID -[hidden]right-> Phone

ModelManager --> "~* filtered" Person
ModelManager --> TagList
ModelManager --> Tag

TagList --> Tag

@enduml
4 changes: 4 additions & 0 deletions docs/diagrams/ParserClasses.puml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Class XYZCommand
package "Parser classes"{
Class "<<interface>>\nParser" as Parser
Class AddressBookParser
Class AccountManagerParser
Class XYZCommandParser
Class CliSyntax
Class ParserUtil
Expand All @@ -20,11 +21,14 @@ Class Prefix

Class HiddenOutside #FFFFFF
HiddenOutside ..> AddressBookParser
HiddenOutside ..> AccountManagerParser

AddressBookParser .down.> XYZCommandParser: <<create>>
AccountManagerParser .down.> XYZCommandParser: <<create>>

XYZCommandParser ..> XYZCommand : <<create>>
AddressBookParser ..> Command : <<use>>
AccountManagerParser ..> Command : <<use>>
XYZCommandParser .up.|> Parser
XYZCommandParser ..> ArgumentMultimap
XYZCommandParser ..> ArgumentTokenizer
Expand Down
10 changes: 8 additions & 2 deletions docs/diagrams/StorageClassDiagram.puml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ Class "<<interface>>\nAddressBookStorage" as AddressBookStorage
Class JsonAddressBookStorage
Class JsonSerializableAddressBook
Class JsonAdaptedPerson
Class JsonAdaptedTag
}

package "TagList Storage" #F4F6F6{
Class "<<interface>>\nTagListStorage" as TagListStorage
Class JsonTagListStorage
Class JsonSerializableTagList
}

Class HiddenOutside #FFFFFF
Expand All @@ -33,11 +36,14 @@ StorageManager -up-> "1" AddressBookStorage

Storage -left-|> UserPrefsStorage
Storage -right-|> AddressBookStorage
Storage -right-|> TagListStorage

JsonUserPrefsStorage .up.|> UserPrefsStorage
JsonAddressBookStorage .up.|> AddressBookStorage
JsonAddressBookStorage ..> JsonSerializableAddressBook
JsonSerializableAddressBook --> "*" JsonAdaptedPerson
JsonAdaptedPerson --> "*" JsonAdaptedTag
JsonTagListStorage -up-.|> TagListStorage
JsonTagListStorage -down-.> JsonSerializableTagList

}
@enduml

0 comments on commit 7dbcce8

Please sign in to comment.