"Principle of least knowledge"
What is it?
A method in an object should only call methods of:
Only talk to your immediate friends
Avoid doing method chaining! (You will lose marks)
o.get(name).get(thing).remove(node)
Purpose?
Achieve loose coupling in code
Cohesion refers to what a class / module can do.
Low cohesion means class has a great variety of actions (broad, unfocused)
High cohesion means a class is focused on what it should be doing
Coupling refers to how dependent classes are toward each other.
High coupling makes it difficult to change your code as classes are so knit together.
Good software design is
high cohesion
and
low coupling
In the unsw.training
package there is some code for a training system.
In the TrainingSystem
class, there is a method to book a seminar for an employee given the dates on which they are available.
This method violates the principle of least knowledge (Law of Demeter).
Where and how is the Law of Demeter being violated?
TrainingSystem
is getting instances of Seminar
from instances of Trainer
and calling its methods
Interacting with classes beyond its friends
public LocalDate bookTraining(String employee, List<LocalDate> availability) {
for (Trainer trainer : trainers) {
for (Seminar seminar : trainer.getSeminars()) {
for (LocalDate available : availability) {
if (seminar.getStart().equals(available) &&
seminar.getAttendees().size() < 10) {
seminar.getAttendees().add(employee);
return available;
}
}
}
}
return null;
}
In violating this principle, what other properties of this design is not desirable?
TrainingSystem
is needlessly tightly coupled with Trainer
and Seminar
TrainingSystem
has low cohesion as it relies on classes that are not its closest friends to achieve its purposeSeminar
has no control over the number of attendees. It relies on TrainingSystem
to restrict number of attendees. This makes Seminar
hard to re-use in the future (poor encapsulation)
In violating this principle, what other properties of this design is not desirable?
Let's refactor it together!
TrainingSystem
is needlessly tightly coupled with Trainer
and Seminar
TrainingSystem
has low cohesion as it relies on classes that are not its closest friends to achieve its purposeSeminar
has no control over the number of attendees. It relies on TrainingSystem
to restrict number of attendees. This makes Seminar
hard to re-use in the future (poor encapsulation)
In violating this principle, what other properties of this design is not desirable?
TrainingSystem
no longer has any knowledge of Seminar
. Seminar
class is responsible for ensuring number of attendees do no exceed 10.In refactoring the principle is no longer violated, how has this affected other properties of the design?
How does OnlineSeminar
violate LSP?
/**
* An online seminar is a video that can
* be viewed at any time by employees.
* A record is kept of which employees
* have watched the seminar.
*/
public class OnlineSeminar extends Seminar {
private String videoURL;
private List<String> watched;
}
How does OnlineSeminar
violate LSP?
/**
* An online seminar is a video that can
* be viewed at any time by employees.
* A record is kept of which employees
* have watched the seminar.
*/
public class OnlineSeminar extends Seminar {
private String videoURL;
private List<String> watched;
}
Does not have a list of attendees, so clients won't be able to use it in the same way as Seminar
.
i.e making a booking
Design patterns are blueprints for solving common design problems efficiently.
They help us make our code:
We are going to learn many different design patterns from this week till the end of the course.
Design patterns are categorised into 3 main types:
I recommend throughout this course noting down:
What specific problem a design pattern is solving
These will be useful for Assignment 2 where you have to choose which is the best design pattern to use and to implement them!
What is it?
Structural design pattern that allow objects to be composed into a tree structure such that individual objects and composites of such objects can be treated in the same way.
When to use?
Model a group of classes that forms a hierarchy
In Unix based operating systems, directories are just files that can contain other files
Leaf Nodes
Composite Nodes
UML Diagram
Leaf
and Composite
both implement the same interfaceLeaf
and Composite
can be treated as the sameComposite
can hold more than one Leaf
Produces a tree-like structure that leans itself very well towards recursion
Use the composite pattern to design a simple calculator that can be used to evaluate an arithmetic expression.
Your calculator should be able to:
Tree representation
exp1 = 42
exp2 = ((1 + 2) - ((3 / 4) * (5))
UML Diagram
composite nodes
leaf node
Why use it?
What is it?
Creational design pattern that lets you define an interface for creating objects of a family in a superclass but allows subclasses to alter the type of object that will be created.
Imagine we are developing a game with different characters!
public class Game {
public static void main(String[] args) {
Game game = new Game();
game.addCharacter(new King(0, 0));
game.addCharacter(new Dragon(0, 1));
game.addCharacter(new Queen(2, 2));
game.play();
}
}
Refactor the code such that when the characters are created, they are put in a random location in a grid of length of length 5.
Here, because our number of characters that are needed to be created is relatively small, we can place all in a single CharactorFactory
class.
CharacterFactory.createKing
etc, which makes our code more clean and less likely for Game
to cause problems with creating the objects itself.How does the Factory Pattern allow us to abstract construction of objects, and how will it improve our design with this new requirement?
There is another version of the Factory pattern where we create a factory for each concrete product.
There is another version of the Factory pattern where we create a factory for each concrete product.
EntityFactory
KingFactory
QueenFactory
Character
King
Queen
When to use it?
What is it?
Creational design pattern that lets you produce families of related objected without specifying concrete classes.
Say we decide to further extend our game, so that we have several variants.
For example, products King
+ Queen
+ Knight
+ Dragon
are available in different variants:
KingdomA
, KingdomB
The abstract factory is the interface with all the creation methods in the product family.
For each family variant, we create a separate factory class
KingdomACharacterFactory
KingdomBCharacterFactory
CharacterFactory
KingdomAKing
KingdomBKing
King