COMP2511 Design Pattern (Part 2)

Week 4 (OO Design Principle)

Design Principle 3

Identify aspects of your code that varies and encapsulate and separate it from code that stays the same, so that it won’t affect your real code.
Another way to think about this principle: take the parts that vary and encapsulate them, so that later you can alter or extend the parts that vary without affecting those that don’t.

Design Principle 4

Program to an interface , not to an implementation

1
2
3
4
5
6
// programming to an implementation:
Dog d = new Dog();
d.bark();
// programming to an interface:
Animal a = new Dog();

Design Principle 5: Hallywood Principle

Don’t call us, we’ll call you

  1. Provides us a way to reduce software rot

  2. The high-level components give the lowlevel components a “don’t call us, we’ll call you’ treatment, i.e., allow low-level components to hook themselves into a system, but the high-level components decide “when” and “how” they are needed

Design Pattern

  1. Design pattern: in software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design.
  • Represents a template for how to solve a problem
  • Capture design expertise and enables this knowledge to be transferred and reused
  • Is not a finished solution, they give you general solutions to design problems

    Strategy Pattern

    This pattern defines a family of algorithms, encapsulates each one

Strategy pattern is a behaviour design pattern that lets the algorithms vary independently from the context class using it

  • This allows you to encapsulate a family of algorithms
  • Enables you to “change behaviour” at run-time

Strategy pattern

example
Benefits: Uses composition over inheritance which allows better decoupling between the behaviour and context class that uses the behaviour

Drawbacks:

  1. increase the number of object.
  2. client must be aware of different strategies

Examples:

  1. Sorting a list (QuickSort, Bubble Sort, merge sort)
  • Encapsulate each sort algorithm into a concrete strategy class
  • Context class decides at run-time, which sorting behaviour is needed
  1. Search (Binary search, DFS, BFS, A*)

State Pattern

This pattern allows an object to alter its behaviour when its internal state changes. The object will appear to change its class.

state pattern

Example:
First we set up a context for our mp3 player:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Context
public class MP3PlayerContext {
private State state;
private MP3PlayerContext(State state) {
this.state= state;
}
public void play() {
state.pressPlay(this);
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}

Now we’ll create our state interface:

1
2
3
private interface State{
public void pressPlay(MP3PlayerContext context);
}

And finally, creating a state for Standby and for Playing:

1
2
3
4
5
6
7
8
9
10
11
public class StandbyState implements State {
public void pressPlay(MP3PlayerContext context) {
context.setState(new PlayingState());
}
}
public class PlayingState implements State {
public void pressPlay(MP3PlayerContext context){
context.setState(new StandbyState());
}
}

Template Method Pattern

The Template Method pattern is a behavioural design pattern that defines the skeleton of an algorithm in a method deferring some steps to sub-classes. The template method lets sub-classes redefine certain steps of an algorithm without changing the algorithm structure

template pattern

Create an abstract class with a template method being final:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
//template method
public final void play(){
//initialize the game
initialize();
//start game
startPlay();
//end game
endPlay();
}
}

Create concrete classes extending the above class:
Cricket.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Cricket extends Game {
@Override
void endPlay() {
System.out.println("Cricket Game Finished!");
}
@Override
void initialize() {
System.out.println("Cricket Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Cricket Game Started. Enjoy the game!");
}
}

Football.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Football extends Game {
@Override
void endPlay() {
System.out.println("Football Game Finished!");
}
@Override
void initialize() {
System.out.println("Football Game Initialized! Start playing.");
}
@Override
void startPlay() {
System.out.println("Football Game Started. Enjoy the game!");
}
}

TemplatePatternDemo.java:

1
2
3
4
5
6
7
8
9
10
public class TemplatePatternDemo {
public static void main(String[] args) {
Game game = new Cricket();
game.play();
System.out.println();
game = new Football();
game.play();
}
}

谢谢你请我吃糖果:)