Skip to content

Commit

Permalink
Tweak LOs to match se-edu/se-book
Browse files Browse the repository at this point in the history
  • Loading branch information
damithc committed Sep 14, 2017
1 parent f714ba6 commit 4645a39
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 31 deletions.
84 changes: 54 additions & 30 deletions doc/LearningOutcomes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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*.<br>
e.g. rename the tag `friends` to `buddies` (i.e. all persons who had the `friends` tag will now have
Expand All @@ -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`
Expand All @@ -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.<br>
Expand All @@ -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,
Expand All @@ -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

Expand All @@ -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`. <br>
Expand All @@ -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. <br>
<img src="images/DependencyInjection.png" width="600">
Expand All @@ -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
Expand All @@ -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

Expand Down
7 changes: 6 additions & 1 deletion src/seedu/addressbook/commands/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ public static String getMessageForPersonListShownSummary(List<? extends ReadOnly
/**
* Executes the command and returns the result.
*/
public abstract CommandResult execute();
public CommandResult execute(){
throw new UnsupportedOperationException("This method should be implement in child classes");
}

//Note: it is better to make the execute() method abstract, by replacing the above method with the line below:
//public abstract CommandResult execute();

/**
* Supplies the data the command will operate on.
Expand Down

0 comments on commit 4645a39

Please sign in to comment.