Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sequence diagram for find command #150

Merged
merged 5 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,20 @@ Classes used by multiple components are in the `seedu.addressbook.commons` packa

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

### Find feature

The following sequence diagram shows how a `find David` command is executed.

<puml src="diagrams/FindSequenceDiagram.puml" alt="Interactions between components for the `find David` Command" />
<br><br>

### Undo/Redo feature

The undo/redo mechanism is implemented within `AddressBook.java` by saving the entire `persons` list. It uses an undo and a redo stack to maintain the history. Additionally, it implements the following operations:

* `AddressBook#save()` — Copies the current `persons` list into the `undoStack`.
* `AddressBook#undo()` — Restores the previous `persons` list state from the `undoStack`.
* `AddressBook#redo()` — Restores a previously undone `persons` list state from the `redoStack`.
* `AddressBook#save()`Copies the current `persons` list into the `undoStack`.
* `AddressBook#undo()`Restores the previous `persons` list state from the `undoStack`.
* `AddressBook#redo()`Restores a previously undone `persons` list state from the `redoStack`.

`save()` is used within the `AddressBook` class methods, saving only when the persons list is about to be modified. `save()` is set to be private to prevent potential misuse from other classes, and Law of Demeter violations.

Expand All @@ -173,7 +180,7 @@ Step 2. The user executes `delete 5` command to delete the 5th person in the add

<puml src="diagrams/UndoRedoState1.puml" alt="UndoRedoState1" />

Step 3. The user executes `add n/David …​` to add a new person. The `add` command also calls `save()`, causing another `persons` list state (State 1) to be saved into the `undoStack`, before adding the person (State 2).
Step 3. The user executes `add n/David ...` to add a new person. The `add` command also calls `save()`, causing another `persons` list state (State 1) to be saved into the `undoStack`, before adding the person (State 2).

<puml src="diagrams/UndoRedoState2.puml" alt="UndoRedoState2" />

Expand Down Expand Up @@ -213,7 +220,7 @@ Similarly, how an undo operation goes through the `Model` component is shown bel

<puml src="diagrams/UndoSequenceDiagram-Model.puml" alt="UndoSequenceDiagram-Model" />

The `redo` command does the opposite — it calls `Model#redo()`, which will:
The `redo` command does the oppositeit calls `Model#redo()`, which will:
1. Copy the `persons` list into the `undoStack`.
2. Pop the latest `persons` list state from the `redoStack`.
3. Copy this popped state into the `persons` list.
Expand All @@ -231,13 +238,14 @@ Step 5. The user then decides to execute the command `list`. Commands that do no
Step 6. The user executes `clear`, which calls `AddressBook#save()`.
Since there are still states in the `redoStack`, all states in the `redoStack` will be removed.

Reason: It no longer makes sense to redo the `add n/David …​` command and ignore the `clear` command. This is the behavior that most modern desktop applications follow.
Reason: It no longer makes sense to redo the `add n/David ...` command and ignore the `clear` command. This is the behavior that most modern desktop applications follow.

<puml src="diagrams/UndoRedoState5.puml" alt="UndoRedoState5" />

The following activity diagram summarizes what happens when a user executes a new command (excluding undo & redo):

<puml src="diagrams/SaveActivityDiagram.puml" width="250" />
<br><br>

#### Design considerations:

Expand Down Expand Up @@ -358,7 +366,7 @@ Therefore, the application aims to deliver the following:

Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unlikely to have) - `*`

| Priority | As a | I want to | So that I can |
| Priority | As a ... | I want to ... | So that I can ... |
|-----------|---------------|-------------------------------------------------------------------|-------------------------------------------------------------------------------------|
| `* * *` | user | add new contacts and assets | keep track of these details |
| `* * ` | user | add tags to contacts | categorize them according to my preferences and workflow |
Expand Down Expand Up @@ -539,7 +547,7 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
* **Mainstream OS**: Windows, Linux, Unix, MacOS
* **Person-In-Charge(PIC)**: A contact responsible for an asset
* **Point-of-Contact(PoC)**: A contact representing a responsible entity like a department or external business
* **Tag**: User added information associated to a contact e.g. `retired`, `temp staff`,
* **Tag**: User added information associated to a contact e.g. `retired`, `temp staff`, ...

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

Expand Down Expand Up @@ -569,7 +577,7 @@ testers are expected to do more *exploratory* testing.
1. Re-launch the app by double-clicking the jar file.<br>
Expected: The most recent window size and location is retained.

1. _{ more test cases …​ }_
1. _{ more test cases ... }_

### Deleting a person

Expand All @@ -586,12 +594,13 @@ testers are expected to do more *exploratory* testing.
1. Other incorrect delete commands to try: `delete`, `delete x`, `...` (where x is larger than the list size)<br>
Expected: Similar to previous.

1. _{ more test cases …​ }_
1. _{ more test cases ... }_

### Saving data

1. Dealing with missing/corrupted data files

1. _{explain how to simulate a missing/corrupted file, and the expected behavior}_
</li>

1. _{ more test cases …​ }_
1. _{ more test cases ... }_
82 changes: 82 additions & 0 deletions docs/diagrams/FindSequenceDiagram.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@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 "<<class>>\nCommandType" as CommandTypeClass LOGIC_COLOR
participant "commandType:CommandType" as CommandType LOGIC_COLOR
participant "<<class>>\nFindCommand" as FindCommandClass LOGIC_COLOR
participant "command:FindCommand" as FindCommand LOGIC_COLOR
end box

box Model MODEL_COLOR_T1
participant "predicate:PersonMatchesKeywordsPredicate" as PersonMatchesKeywordsPredicate MODEL_COLOR
participant "model:Model" as Model MODEL_COLOR
end box

[-> LogicManager : execute("find David")
activate LogicManager

LogicManager -> AddressBookParser : parseCommand("find David")
activate AddressBookParser

AddressBookParser -> CommandTypeClass : valueOf("FIND")
activate CommandTypeClass

create CommandType
CommandTypeClass -> CommandType
activate CommandType

CommandType --> CommandTypeClass : commandType
deactivate CommandType

CommandTypeClass --> AddressBookParser : commandType
deactivate CommandTypeClass

AddressBookParser -> CommandType : createCommand(" David")
activate CommandType

CommandType -> FindCommandClass : of(" David")
activate FindCommandClass

create PersonMatchesKeywordsPredicate
FindCommandClass -> PersonMatchesKeywordsPredicate : PersonMatchesKeywordsPredicate(["David"])
activate PersonMatchesKeywordsPredicate

PersonMatchesKeywordsPredicate --> FindCommandClass : predicate
deactivate PersonMatchesKeywordsPredicate

create FindCommand
FindCommandClass -> FindCommand : FindCommand(predicate)
activate FindCommand

FindCommand --> FindCommandClass : command
deactivate FindCommand

FindCommandClass --> CommandType : command
deactivate FindCommandClass

CommandType --> AddressBookParser : command
deactivate CommandType

AddressBookParser --> LogicManager : command
deactivate AddressBookParser


LogicManager -> FindCommand : execute(model)
activate FindCommand

FindCommand -> Model : updateFilteredPersonList(predicate)
activate Model

Model --> FindCommand
deactivate Model

FindCommand --> LogicManager : commandResult
deactivate FindCommand

[<--LogicManager : commandResult
deactivate LogicManager
@enduml
10 changes: 5 additions & 5 deletions src/main/java/seedu/address/logic/util/AddressBookParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,23 @@ public static Command parseCommand(String userInput) throws ParseException {
// Lower level log messages are used sparingly to minimize noise in the code.
logger.fine("Command word: " + commandWord + "; Arguments: " + arguments);

CommandType resultType;
CommandType commandType;
try {
resultType = CommandType.valueOf(commandWord.toUpperCase());
commandType = CommandType.valueOf(commandWord.toUpperCase());
} catch (IllegalArgumentException ie) {
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
}

Command result;
Command command;
try {
result = resultType.createCommand(arguments);
command = commandType.createCommand(arguments);
} catch (IllegalArgumentException ie) {
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(ie.getMessage());
}

return result;
return command;
}

}