diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index ef0bb29943c..8021f1a9712 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -115,7 +115,7 @@ NOTE: The lifeline for `DeleteCommandParser` should end at the destroy marker (X === Model component .Structure of the Model Component -image::BetterModelClassDiagram.png[] +image::ModelClassDiagram.png[] *API* : link:{repoURL}/src/main/java/seedu/exercise/model/Model.java[`Model.java`] @@ -439,6 +439,51 @@ Ultimately, Alternative 1 is selected as we believe it is more important to dist from the default ones. This separation ensures that methods meant to operate on custom properties are unable to operate on default properties. +=== Suggest +==== Implementation +The suggest feature is used to recommend exercises to both beginners and experienced users. +The user is allowed to specify what type of suggestions to see. + +The following activity diagram summarizes what happens when a user enters a suggest command: + +image::SuggestActivityDiagram.png[] + +The following sequence diagram shows the sequence flow from the when a user enters a valid `SuggestPossibleCommand`: + +image::SuggestSequenceDiagram.png[] + +From the sequence diagram: + +1. When the `LogicManager` receive the `execute` command, it calls the `parseCommand` method of `ExerciseBookParser`. + +2. `ExerciseBookParser` will receive `suggest` as the command type and instantiate `SuggestCommandParser` to further parse the command. + +3. `SuggestCommandParser` will receive `s/possible` as the suggest type and instantiate `SuggestPossibleCommand` with `muscles` and `customProperties` as constructor parameters. + +4. The `SuggestPossibleCommand` object is then returned to `SuggestCommandParser`, `ExerciseBookParser` and lastly back to `LogicManager` to execute. + +5. `LogicManager` will proceed to call execute `SuggestPossibleCommand`. + +6. When `SuggestPossibleCommand` is executed, it calls a self invocated method, `getPredicate`, which is created based on the `targetMuscles` and `targetCustomProperties`. + +7. `SuggestPossibleCommand` then calls the `updateSuggestedExerciseList` method in `ModelManager`, passing in the predicate to filter the list of suggest exercises. + +8. `SuggestPossibleCommand` creates a new `CommandResult` to be returned. + +==== Design Considerations +===== Aspect: Implementation of predicate creation +* **Alternative 1(current choice): ** `SuggestPossibleCommand` to handle the predicates. +** Pros: +*** Easy to implement and understand. The class `SuggestPossibleCommand` contains the parsing and creation of the predicate all in one place. +** Cons: +*** Violation of SRP as `SuggestPossibleCommand`, in addition to updating the model, has to create the predicate. +* **Alternative 2: ** Predicate Factory class to handles all predicates. +** Pros: +*** Adheres to SRP and Separation of Concern (SoC). +** Cons: +*** May increase coupling because classes that use predicates have to depend on this class. + + === Statistics ==== Implementation diff --git a/docs/diagrams/SuggestActivityDiagram.puml b/docs/diagrams/SuggestActivityDiagram.puml new file mode 100644 index 00000000000..e907a2e9f4b --- /dev/null +++ b/docs/diagrams/SuggestActivityDiagram.puml @@ -0,0 +1,24 @@ +@startuml +skinparam activityShape rectangle + +start +:Entered suggest command; +:check if suggest type is valid; +if() then ([Valid suggest type]) + +if() then ([suggest type == "basic"]) + :updates list to show basic exercises; +else ([suggest type == "possible"]) + if() then ([valid arguments]) + :Form predicate; + :updates list to show exercises with matching predicate; + else ([Invalid arguments]) + :show invalid arguments message; + endif + endif +else ([Invalid suggest type]) + :show invalid suggest type message; +endif +-> Program resumes; +stop +@enduml diff --git a/docs/diagrams/SuggestSequenceDiagram.puml b/docs/diagrams/SuggestSequenceDiagram.puml new file mode 100644 index 00000000000..70ec23a750a --- /dev/null +++ b/docs/diagrams/SuggestSequenceDiagram.puml @@ -0,0 +1,76 @@ +@startuml +!include style.puml + +box Logic LOGIC_COLOR_T1 +participant ":LogicManager" as LogicManager LOGIC_COLOR +participant ":ExerciseBookParser" as ExerciseBookParser LOGIC_COLOR +participant ":SuggestCommandParser" as SuggestCommandParser LOGIC_COLOR +participant "s:SuggestPossibleCommand" as SuggestPossibleCommand LOGIC_COLOR +participant ":CommandResult" as CommandResult LOGIC_COLOR +end box + +box Model MODEL_COLOR_T1 +participant ":Model" as Model MODEL_COLOR +end box + +[-> LogicManager : execute("suggest s/possible m/Leg") +activate LogicManager + +LogicManager -> ExerciseBookParser : parseCommand("suggest s/possible m/Leg") +activate ExerciseBookParser + +create SuggestCommandParser +ExerciseBookParser -> SuggestCommandParser +activate SuggestCommandParser + +SuggestCommandParser --> ExerciseBookParser +deactivate SuggestCommandParser + +ExerciseBookParser -> SuggestCommandParser : parse("s/possible m/Leg") +activate SuggestCommandParser + +create SuggestPossibleCommand +SuggestCommandParser -> SuggestPossibleCommand : (muscles, customProperties) +activate SuggestPossibleCommand + +SuggestPossibleCommand --> SuggestCommandParser : s +deactivate SuggestPossibleCommand + +SuggestCommandParser --> ExerciseBookParser : s +deactivate SuggestCommandParser + +'Hidden arrow to position the destroy marker below the end of the activation bar. +SuggestCommandParser -[hidden]-> ExerciseBookParser +destroy SuggestCommandParser + +ExerciseBookParser --> LogicManager : s +deactivate ExerciseBookParser + +LogicManager -> SuggestPossibleCommand : execute() +activate SuggestPossibleCommand + +SuggestPossibleCommand --> SuggestPossibleCommand : getPredicate() +activate SuggestPossibleCommand + +SuggestPossibleCommand --> SuggestPossibleCommand :p +deactivate SuggestPossibleCommand + +SuggestPossibleCommand -> Model : updateSuggestedExerciseList(p) +activate Model + +Model --> SuggestPossibleCommand +deactivate Model + +create CommandResult +SuggestPossibleCommand -> CommandResult +activate CommandResult + +CommandResult --> SuggestPossibleCommand : result +deactivate CommandResult + +SuggestPossibleCommand --> LogicManager : result +deactivate SuggestPossibleCommand + +[<--LogicManager : result +deactivate LogicManager +@enduml diff --git a/docs/images/SuggestActivityDiagram.png b/docs/images/SuggestActivityDiagram.png new file mode 100644 index 00000000000..6c3b7fe1fcd Binary files /dev/null and b/docs/images/SuggestActivityDiagram.png differ diff --git a/docs/images/SuggestClassDiagram.png b/docs/images/SuggestClassDiagram.png new file mode 100644 index 00000000000..96a6e538cf1 Binary files /dev/null and b/docs/images/SuggestClassDiagram.png differ diff --git a/docs/images/SuggestSequenceDiagram.png b/docs/images/SuggestSequenceDiagram.png new file mode 100644 index 00000000000..5afdcc0573c Binary files /dev/null and b/docs/images/SuggestSequenceDiagram.png differ