diff --git a/doc/LearningOutcomes.md b/doc/LearningOutcomes.md index 8a2d6c876..e4bf5f468 100644 --- a/doc/LearningOutcomes.md +++ b/doc/LearningOutcomes.md @@ -12,11 +12,15 @@ After studying this code and completing the corresponding exercises, you should 1. [Apply Dependency Inversion Principle `[LO-DIP]`](#apply-dependency-inversion-principle-lo-dip) 1. [Use Dependency Injection `[LO-DI]`](#use-dependency-injection-lo-di) 1. [Apply Open-Closed Principle `[LO-OCP]`](#apply-open-closed-principle-lo-ocp) -1. [Work in a 2KLoC code base `[LO-2KLoC]`](#work-in-a-2kloc-code-base-lo-2kloc) +1. [Work in a 3KLoC code base `[LO-3KLoC]`](#work-in-a-3kloc-code-base-lo-3kloc) ------------------------------------------------------------------------------------------------------ ## Utilize User Stories `[LO-UserStories]` + +#### References + +* [se-edu/se-book: Requirements: Specifying Requirements: User Stories](https://se-edu.github.io/se-book/specifyingRequirements/userStories/) #### Exercise: Add more user stories @@ -27,6 +31,10 @@ After studying this code and completing the corresponding exercises, you should ## Utilize use cases `[LO-UseCases]` +#### References + +* [se-edu/se-book: Requirements: Specifying Requirements: Use Cases](https://se-edu.github.io/se-book/specifyingRequirements/useCases/) + #### Exercise: Add a 'Rename tag' use case * Add a use case to the `DeveloperGuide.md` to cover the case of *renaming of an existing tag*.
e.g. rename the tag `friends` to `buddies` (i.e. all persons who had the `friends` tag will now have @@ -37,6 +45,10 @@ After studying this code and completing the corresponding exercises, you should ## Use Non Functional Requirements `[LO-NFR]` +#### References + +* [se-edu/se-book: Requirements: Non-Functional Requirements](https://se-edu.github.io/se-book/requirements/nonFunctionalRequirements/) + #### Exercise: Add more NFRs * Add some more NFRs to the `DeveloperGuide.md` @@ -45,11 +57,15 @@ After studying this code and completing the corresponding exercises, you should ## Use Polymorphism `[LO-Polymorphism]` -Note how the `Command::execute()` method shows polymorphic behavior. +Note how the `Command::execute()` method shows polymorphic behavior. + +#### References + +* [se-edu/se-book: Implementation: OOP: Polymorphism](https://se-edu.github.io/se-book/oopImplementation/polymorphism/) #### Exercise: Add a polymorphic `isMutating` method -* Add an `abstract` method `boolean isMutating()` to the `Command` class. This method will return `true` for +* Add a method `boolean isMutating()` to the `Command` class. This method will return `true` for command types that mutate the data. e.g. `AddCommand` * Currently, AddressBook data are saved to the file after every command. Take advantage of the the new method you added to limit file saving to only for command types that mutate data.
@@ -62,12 +78,22 @@ Note: There may be better ways to limit file saving to commands that mutate data ## Use abstract classes/methods `[LO-Abstract]` -Covered by `[LO-Polymorphism]` +#### References + +* [se-edu/se-book: Implementation: OOP: Abstract Classes](https://se-edu.github.io/se-book/oopImplementation/abstractClasses/) + +#### Exercise: Make `Command#execute()` method abstract + +* Make the `Command#execute()` method abstract (hint: refer to the comment given below the method) ------------------------------------------------------------------------------------------------------ ## Follow Liskov Substitution Principle `[LO-LSP]` +#### References + +* [se-edu/se-book: Principles: Liskov Substitution Principle](https://se-edu.github.io/se-book/principles/liskovSubstitutionPrinciple/) + #### Exercise: Add an exception to an overridden method * Add a `throws Exception` clause to the `AddCommand::execute` method. Notice how Java compiler will not allow it, @@ -82,25 +108,24 @@ Covered by `[LO-Polymorphism]` ## Use Java-FX for GUI programming `[LO-JavaFx]` -**Resources** +#### References -* [JavaFX 8 Tutorial](https://se-edu.github.io/se-book/javaTools/javaFXBasic/) +* [se-edu/se-book: Tools: Java: JavaFX: Basic](https://se-edu.github.io/se-book/javaTools/javaFXBasic/) -#### Exercise: Add class-level members +#### Exercise: Enhance GUI -* If you are new to JavaFX, follow our tutorial given above. -* Do some enhancements to the AddressBook GUI. e.g. add an application icon, change size/style +* Do some enhancements to the AddressBook GUI. e.g. add an application icon, change font size/style ------------------------------------------------------------------------------------------------------ ## Analyze Coupling and Cohesion of designs `[LO-CouplingCohesion]` -* Ensure you know the answers to these questions: - * What is the _Coupling_? - * What is _Cohesion_? -* As you saw above, DIP helps us to avoid *coupling* from higher-level classes to lower-level classes. -* Notice how having a separate `Formattter` class (an application of SIP) improves the *cohesion* of - the `MainWindow` class as well as the `Formatter` class. +* Notice how having a separate `Formattter` class (an application of the Single Responsibility Principle) improves the *cohesion* of the `MainWindow` class as well as the `Formatter` class. + +#### References + +* [se-edu/se-book: Design: Design Principles: Coupling](https://se-edu.github.io/se-book/designPrinciples/coupling/) +* [se-edu/se-book: Design: Design Principles: Cohesion](https://se-edu.github.io/se-book/designPrinciples/cohesion/) #### Exercise: Identify places to reduce coupling and increase cohesion @@ -110,11 +135,12 @@ Covered by `[LO-Polymorphism]` ## Apply Dependency Inversion Principle `[LO-DIP]` +#### References + +* [se-edu/se-book: Principles: Dependency Inversion Principle](https://se-edu.github.io/se-book/principles/dependencyInversionPrinciple/) + #### Exercise: Invert dependency from Logic to Storage -* Ensure you know the answers to these questions: - * What is the _Dependency Inversion Principle_? - * How does DIP help? * Note how `Logic` class depends on the `StorageFile` class. This is a violation of DIP. * Modify the implementation as follows so that both `Logic` and `StorageFile` now depend on the `abstract` class `Storage`.
@@ -129,11 +155,12 @@ Note how `Logic` class depends on the `StorageFile` class. This means when testi our test cases execute the `StorageFile` class as well. What if we want to test the `Logic` class without getting the `StorageFile` class involved? That is a situation where we can use *Dependency Injection*. +#### References + +* [se-edu/se-book: Quality Assurance: Testing: Dependency Injection](https://se-edu.github.io/se-book/testing/dependencyInjection/) + #### Exercise: Facilitate injecting a StorageStub -* Ensure you know the answers to these questions: - * What is the _Dependency Injection_? - * How does DI help? * Change the implementation as follows so that we can inject a `StorageStub` when testing the `Logic` class.
@@ -156,16 +183,13 @@ getting the `StorageFile` class involved? That is a situation where we can use * ## Apply Open-Closed Principle `[LO-OCP]` +#### References +* [se-edu/se-book: Design: Desing Principles: Open-Closed Principle](https://se-edu.github.io/se-book/designPrinciples/openClosedPrinciple/) + #### Exercise: Analyze OCP-compliance of the `Logic` class -* Ensure you know the answers to these questions: - * What is the _Open Closed Principle_? - * How does OCP help? -* Consider adding a new command to the Address Book. e.g. an `edit` command. -* Notice how little you need to change in the `Logic` class to extend its behavior so that it can execute - the new command. - That is because `Logic` follows the OCP i.e. `Logic` is *open to be extended* with more - commands but *closed for modifications*. +* Consider adding a new command to the Address Book. e.g. an `edit` command. Notice how little you need to change in the `Logic` class to extend its behavior so that it can execute the new command. + That is because `Logic` follows the OCP i.e. `Logic` is *open to be extended* with more commands but *closed for modifications*. * Is it possible to make the `Parser` class more OCP-compliant in terms of extending it to handle more command types? * In terms of how it saves data, does `Logic` become more OCP-compliant @@ -175,7 +199,7 @@ getting the `StorageFile` class involved? That is a situation where we can use * ------------------------------------------------------------------------------------------------------ -## Work in a 2KLoC code base `[LO-2KLoC]` +## Work in a 3KLoC code base `[LO-3KLoC]` #### Exercise: Enhance AddressBook diff --git a/src/seedu/addressbook/commands/Command.java b/src/seedu/addressbook/commands/Command.java index ccd4fcbf4..a54cbcb5b 100644 --- a/src/seedu/addressbook/commands/Command.java +++ b/src/seedu/addressbook/commands/Command.java @@ -39,7 +39,12 @@ public static String getMessageForPersonListShownSummary(List