Design pattern

61
Design Pattern Thibaut de Broca

Transcript of Design pattern

Page 1: Design pattern

Design PatternThibaut de Broca

Page 2: Design pattern

Introduction

Page 3: Design pattern

History1977: Christopher Alexander introduces the idea of patterns: successful solutions to problems. (Pattern Language)

1987: Ward Cunningham and Kent Beck leverage Alexander’s idea in the context of an OO language.

1987: Eric Gamma’s dissertation on importance of patterns and how to capture them.

1994: The book ====>

DefinitionIn software engineering, a software design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. It is not a finished design that can be transformed directly into source or machine code.

Page 4: Design pattern

Fundamental Principles

Page 5: Design pattern

‘Avoid Tight coupling’

Fundamental Principles

Page 6: Design pattern

‘Code as modular black boxes’ && ‘Single responsibility principles’

Fundamental Principles

Page 7: Design pattern

‘Program to an interface and not to an implementation’

The class shouldn’t care about which class they use, but more which behaviour they will use.

To send messages from class to class, send interfaces not classes.

Be careful ! Don’t over-use interface => 1 class != 1 interface

Fundamental Principles

Page 8: Design pattern

public class Main { public static void main(String[] args) { Animal[] animals = new Animal[3]; animals[0] = new Dog(); animals[1] = new Cat(); animals[2] = new Fox(); for (Animal animal : animals) { animal.speak(); } }

}

An interface is a reference type in Java.

It is similar to class. It is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. Along with abstract methods, an interface may also contain constants, default methods, static methods, and nested types.

Interlude: Interface - Recall

Animal

Dog Cat Fox

public interface Animal { public void speak();}public class Dog implements Animal { public void speak() {System.out.println("Wouaf Wouaf!");}}public class Cat implements Animal { public void speak() {System.out.println("Miaouh!");}}public class Fox implements Animal { public void speak() { System.out.println("What does the Fox say ?"); }}

Page 9: Design pattern

‘Favor Object Composition over inheritance’

The class shouldn’t care about which class they use, but more which behaviour they will use.

To send messages from class to class, send interfaces not classes.

Bad use of inheritance:

My personal opinion is that there is no "better" or "worse" principle to design. There is "appropriate" and "inadequate" design for the concrete task. In

other words - I use both inheritance or composition, depending on the situation. The goal is to produce smaller code, easier to read, reuse and

eventually extend further.

class Stack extends ArrayList {

public void push(Object value) { … }

public Object pop() { … }

}

Fundamental Principles

1

4

54

2

class Stack extends {

private ArrayList myList;

public void push(Object value) { … }

public Object pop() { … }

}

Page 10: Design pattern

‘A design must be open for extension but closed for modification’ (Open/Close Principle)

=> Once a class is written, you should not have to modify it to add new functionality.

Fundamental Principles

Page 11: Design pattern

‘Avoid Duplication’

Fundamental Principles

Page 12: Design pattern

- SRP: Single Responsibility Principle

- OCP: Open Close Principle

- LSP: Liskov Substitution Principle. (Derived classes must be substitutable for their base classes).

- ISP: Interface Segregation Principle. (Client should not be forced to depend upon interfaces they do not use).

- DIP: Dependency Inversion Principle. High level modules should not depend upon low level modules. Both should depend upon abstraction).

Example code to improve: https://github.com/WANdisco/hive-metastore-sync/blob/master/src/com/wandisco/hivesync/common/Tools.java#L37

Fundamental Principles

Page 13: Design pattern

Keep in mind: “When Coding, 80% of your time is spent by reading code”. So take care of formatting and naming !

Others Principles

Page 14: Design pattern

- DRY: Don’t Repeat Yourself. Can Lead to maintenance nightmare

- YAGNI: You ain’t gonna need it. Do not add functionality until necessary.

- KISS: Keep It Simple, Stupid. Avoid accidental complexity.

- Boy Scout Rules: Always leave the campground cleaner than you found it.

Others Principles

Page 15: Design pattern

UML Recalls

Page 16: Design pattern

Class Diagram

· Upper part contains the name of the class· Middle part describes attributes of the class· Bottom part describes the methods of the class

public class Example { public static int CONSTANT= 0;

private String attribute1;

public String method() { return attribute1; }

private static void privateMethod(int c) { CONSTANT+=c; }}

UML - Recalls

Page 17: Design pattern

Relations between classes

The simplest of relation :

· Class A depends on Class B if, at some point, it uses Class B· Symbolized by dotted line and and open arrow indicating the dependency direction

public class A { public String method(B b) { return b.toString(); }}

public class B { public toString() { return "B"; }}

UML - Recalls

Page 18: Design pattern

Association

Stronger dependency from class A to class B, namely, A uses and contains an instance of class B:· It is represented by a plain line and an open arrow· This association can have a cardinality 0..1 or 1..n· It is directed , in the example below A knows B, but B does not know anything about A

public class A { private B b; public void setB(B b) { this.b = b; }}

public class B { public toString() { return "B"; }}

UML - Recalls

Page 19: Design pattern

Aggregation

Our example models Rockband and members. A rockband can have several members. And Members can be in several Rockand.

The addition of the diamond adds information about the life of the objects· The empty diamond signifies that ‘Member’ objects can be shared between several ‘RockBand’ objects· When an ‘RockBand’ object is destroyed, then the instances of ‘Member’ it was associated with do not disappear.

UML - Recalls

Page 20: Design pattern

Composition

· The plain/full diamond indicates that the contained objects are not shared· When the container object is destroyed, the contained objects disappear with it

UML - Recalls

class Tattoo { String description; public Tattoo(String description) { this.description = description; }}class Member { private String name; private List<Tattoo> tattoos = new ArrayList<>(); [...] public ink(String description) { tattoos.add(new Tattoo(description)); } }

class RockBand { private List<Member> members = new ArrayList<>();

public void addMember(Member m) { members.add(m); } public Member getMember(int num) { return members.get(num); } public void toString() { [..] }}

Page 21: Design pattern

Inheritance / Generalization

· Inheritance enables to create classes hierarchies sharing same attributes· Children classes also have the attributes and methods of the parent classes,· These attributes and methods are defined for the objects the children classes.· This mechanism enables Polymorphism

Properties· Transitivity: If B inherits from A and C inherits from B then C inherits from A· Not reflexive: No class can inherit from itself· Not symmetric: If B inherits from A, A does not inherit from B· Not cyclic : If B inherits from A and C inherits from B then A can't inherit from C

UML - Recalls

Page 22: Design pattern

Inheritance / Generalization - Codepublic class Animal { private String name; public Animal(String name) { this.name = name; } public String getName() { return this.name; }}

public class Cat extends Animal { public Cat(String name) { super(name); // Call to the parent class constructor } public void meow() { System.out.println("Miaou " + super.getName() + " Miaou"); }}

public class Dog extends Animal { public Dog(String name) { super(name); // Call to the parent class constructor } public void bark() { System.out.println("Wouf " + super.getName() + " Wouf"); }}

UML - Recalls

Page 23: Design pattern

Design Patterns

Page 24: Design pattern

Pattern Catalogue

5 mains classes

Page 25: Design pattern

Creational Pattern

Creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable for the situation.

- Factory Method Pattern

- Abstract Factory

- Singleton

- Builder

- Prototype

Page 26: Design pattern

Intent:

It allows to create objects without specifying their class (method whose main goal is to create a class instance).

Application:

- A class can not anticipate the type of objects it must create (i.e.: framework).

- A class wants its subclasses to specify the type of objects it creates.

- A class needs controls over the creation of its objects.

Factory Method Pattern

// Problem: A depends on Bpublic class A { public void doIt() { B b = new B() }}

Page 27: Design pattern

Structure:

public abstract class Animal() {}public class Dog extend Animal() {}public class Cat extend Animal() {}public class Dolphin extend Animal() {}

public interface AnimalFactory { abstract public Animal create(String type);}

public AnimalFactory () { public Animal create(String type) { switch(type) { case "Dog": return new Dog(); break; case "Cat": return new Cat(); break; case "Dolphin": return new Dolphin(); break; default : throw Exception("Animal " + type + " is unknown."); } }}

public Main() { public static void main(String[] args) { Animalfactory factory = new Animalfactory(); Animal cat = factory.create("cat"); }}

Factory Method Pattern

Page 28: Design pattern

Intent:

We want to have only one instance of a class.

Application:

- Instantiate an object can take time and memory.

- We only need one instance.

// Example:// Problem: For factory, we only need one instance

Singleton Pattern

Page 29: Design pattern

Singleton Pattern

Structure:

The trick is to use a static variable to remember the instance.

Then, why not to create a static method ?

The big difference between a singleton and a bunch of static methods is that singletons can implement interfaces, so you can pass around the singleton as if it were "just another" implementation.

MyClass

- static MyClass myClass;

static getInstance(): MyClass

C

public class AnimalFactory { private AnimalFactory();

private static AnimalFactory animalFactory;

public static AnimalFactory getInstance() { if (animalFactory == null) { animalFactory = new AnimalFactory(); } return animalFactory; } //…...}

public Main() { public static void main(String[] args) { Animal cat = Animalfactory.getInstance().create("cat"); }}

Page 30: Design pattern

Creational Pattern

- Factory Method Pattern

- Abstract Factory

- Singleton

- Builder

- Prototype (très utilisé dans Javascript)

Page 31: Design pattern

Behavioral PatternBehavioral patterns are concerned with the assignment of responsibilities between objects, or, encapsulating behavior in an object and delegating requests to it.

- Observer- Strategy

- State

- Visitor

- Memento

- Mediator

- Iterator

- Interpreter

- Template Method

- Chain of Responsibility

- Command

Page 32: Design pattern

Intent:

Supports a relation One To Many so that several objects get notified when an object changes its state and can react.

Application:

- Widely use with IHM when several elements of the view change when the model changes.

Observer Pattern

Page 33: Design pattern

Roles: subject and several observers

- Subject:

- Can modify his state.

- He notifies observers when he has changed.

- Can give his new state

- Observers

- Can subscribe/unsubscribe to a subject

- Are Notified.

- Can get the new state of a subject.

Observer Pattern

subscribe

Page 34: Design pattern

public abstract class AbstractSubject { private List<Observer> observers = new ArrayList<Observer>();

public void attach(Observer observer){observers.add(observer);}

public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } }

public class Subject extends AbstractSubject{ private int state; public int getState() {return state;}

public void setState(int state) { this.state = state; notifyAllObservers(); }}public class BinaryObserver extends Observer{ public BinaryObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); }}

public class ObserverPatternDemo { public static void main(String[] args) { AbstractSubject subject = new Subject();

new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject);

System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); }}

Observer Pattern

Page 35: Design pattern

Observer Pattern

Abstract Subject => Classe java.util.Observable

- addObserver(Observer obs)

- notifyObservers();

Concrete Subject => extends Observable

- When state change, you should call notifyObservers();

Abstract Observer: Interface java.util.Observer

- update(Observable obs, Object args);

Concrete Observer: implements java.util.Observer

- Should implement update(...)

Page 36: Design pattern

Behavioral Pattern

- Observer

- Strategy

- State

- Visitor

- Memento

- Mediator

- Iterator

- Interpreter

- Template Method

- Chain of Responsibility

- Command

Page 37: Design pattern

Intent:

It allows to switch between differents algorithms to accomplish a task.

Application:

- Different variants of an algorithm

- Many related classes differ only in their behaviour

Strategy Pattern

Page 38: Design pattern

Subject => Interface to outside world

Strategy (Algorithm) => common interface for the differents algorithms.

Strategy Pattern

Page 39: Design pattern

Program

- Input: read file

- Output: filtered file

Examples of 4 filters:

- No filtering

- Only words that start with t

- Only words longer than 5 characters

- Only words that are palindroms

LAVAL KAYAK LEVEL

Strategy Pattern - Example

Page 40: Design pattern

public class StrategyPattern { public static void main(String[] args) { Context context = new Context(); String filename = args[0]; System.out.println("\n* Default(Alll): "); context.filter(filename);

System.out.println("\n* Start with T: "); context.changeStrategy(new StartWithT()); context.filter(filename); }}

public interface CheckStrategy { public boolean check(String s);}public class All implements CheckStrategy { @Override public boolean check(String s) { return true; }}public class StartWithT implements CheckStrategy { @Override public boolean check(String s) { return s != null && s.startWith("t"); }}

public class Context { private CheckStrategy strategy; public Context() {this.strategy = new All();} public void changeStrategy(CheckStrategy strategy) { this.strategy = strategy; } public void filter(String filename) throws IOException { BufferedReader infile = new BufferedReader(new FileReader(filename)); String buffer = null; while ((buffer = infile.readLine() != null) { StringTokenizer word = new StringTokenizer(buffer); while (words.hasMoreTokens()) { String word = words.nextToken(); if (strategy.check(word)) { Ssytem.out.println(word); } } } }}

Strategy Pattern - Example

Page 41: Design pattern

Behavioral Pattern

- Observer

- Strategy

- State

- Visitor

- Memento

- Mediator

- Iterator

- Interpreter

- Template Method

- Chain of Responsibility

- Command

Page 42: Design pattern

State Pattern

Intent:

Implements a state machine in an object-oriented way.

It lets an object show other methods after a change of internal state.

Application:

- an application is characterized by large and numerous case statements. These cases vector flow of control based on the state of the application.

Page 43: Design pattern

interface Statelike { void writeName(StateContext context, String name);}

class StateLowerCase implements Statelike { @Override public void writeName(final StateContext context, final String name) { System.out.println(name.toLowerCase()); context.setState(new StateMultipleUpperCase()); }}

class StateMultipleUpperCase implements Statelike { /** Counter local to this state */ private int count = 0;

@Override public void writeName(final StateContext context, final String name) { System.out.println(name.toUpperCase()); /* Change state after StateMultipleUpperCase's writeName() gets invoked twice */ if (++count > 1) {context.setState(new StateLowerCase());} }}

class StateContext { private Statelike myState; StateContext() { setState(new StateLowerCase()); } void setState(final Statelike newState) {myState = newState;}

public void writeName(final String name) { myState.writeName(this, name); }}

State Pattern

public class DemoOfClientState { public static void main(String[] args) { final StateContext sc = new StateContext();

sc.writeName("Monday"); sc.writeName("Tuesday"); sc.writeName("Wednesday"); sc.writeName("Thursday"); sc.writeName("Friday"); sc.writeName("Saturday"); sc.writeName("Sunday"); }}

Page 44: Design pattern

Structural Patterns

Design patterns that ease the design by identifying a simple way to realize relationships between entities.

- Proxy

- Decorator

- Facade

- Adapter

- Aggregate

- Bridge

Page 45: Design pattern

Proxy Pattern

Translation in French:Proxy <=> ?????????

Intent:

- A proxy, in its most general form, is a class functioning as an interface to something else.

Application:

- The proxy could interface to anything: a network connection, a large object in memory, a file.

- For sensitive objects: can verify that the caller has the authorization.

Page 46: Design pattern

interface Image { public void displayImage();}// On System Aclass RealImage implements Image { private String filename = null; public RealImage(final String filename) { this.filename = filename; loadImageFromDisk(); }

private void loadImageFromDisk() {System.out.println("Loading " + filename);}

public void displayImage() {System.out.println("Displaying " + filename);}}// On System Bclass ProxyImage implements Image {

private RealImage image = null; private String filename = null; public ProxyImage(final String filename) { this.filename = filename; }

public void displayImage() { if (image == null) { image = new RealImage(filename); } image.displayImage(); }}

class ProxyExample { public static void main(final String[] arguments) { final Image image1 = new ProxyImage("HiRes_10MB_Photo1"); final Image image2 = new ProxyImage("HiRes_10MB_Photo2");

image1.displayImage(); // loading necessary image1.displayImage(); // loading unnecessary image2.displayImage(); // loading necessary image2.displayImage(); // loading unnecessary image1.displayImage(); // loading unnecessary }}

Proxy Pattern - Example

Page 47: Design pattern

- Proxy

- Decorator

- Facade

- Adapter

- Aggregate

- Bridge

Structural Patterns

Page 48: Design pattern

Decorator Pattern

Intent:

- A wrapper that adds functionality to a class. It is stackable.

Application:

- The decorator pattern is often useful for adhering to the “Single Responsibility Principle”.

- It allows functionality to be divided between classes with unique areas of concern.

Page 49: Design pattern

Decorator Patternpublic interface Shape { void draw();}public class Rectangle implements Shape { @Override public void draw() {System.out.println("Shape: Rectangle");}}public class Circle implements Shape { @Override public void draw() {System.out.println("Shape: Circle");}}

public abstract class ShapeDecorator implements Shape { protected Shape decoratedShape;

public ShapeDecorator(Shape decoratedShape){ this.decoratedShape = decoratedShape; }

public void draw(){decoratedShape.draw();}}

public class RedShapeDecorator extends ShapeDecorator {

public RedShapeDecorator(Shape decoratedShape) { super(decoratedShape); }

@Override public void draw() { decoratedShape.draw(); setRedBorder(decoratedShape); }

private void setRedBorder(Shape decoratedShape){ System.out.println("Border Color: Red"); }}

public class DecoratorPatternDemo { public static void main(String[] args) {

Shape circle = new Circle();

Shape redCircle = new RedShapeDecorator(new Circle());

Shape redRectangle = new RedShapeDecorator(new Rectangle()); System.out.println("Circle with normal border"); circle.draw();

System.out.println("\nCircle of red border"); redCircle.draw();

System.out.println("\nRectangle of red border"); redRectangle.draw(); }}

Page 50: Design pattern

- Proxy

- Decorator

- Facade

- Adapter

- Aggregate

- Bridge

Structural Patterns

Page 51: Design pattern

Intent:

- Provide a unified interface to a set of interfaces in a subsystem.

- Defines a higher-level interface that makes the subsystem easier to use.

Application:

- A simple interface is required to access a complex system.

- An entry point is needed to each level of layered software.

Façade Pattern

Page 52: Design pattern

Façade Patternpublic interface Shape { void draw();}public class Rectangle implements Shape { @Override public void draw() {System.out.println("Rectangle::draw()");}}public class Square implements Shape { @Override public void draw() {System.out.println("Square::draw()");}}public class Circle implements Shape { @Override public void draw() {System.out.println("Circle::draw()");}}

public class ShapeMaker { private Shape circle; private Shape rectangle; private Shape square;

public ShapeMaker() { circle = new Circle(); rectangle = new Rectangle(); square = new Square(); } public void drawCircle(){circle.draw();} public void drawRectangle(){rectangle.draw();} public void drawSquare(){square.draw();}}public class FacadePatternDemo { public static void main(String[] args) { ShapeMaker shapeMaker = new ShapeMaker(); shapeMaker.drawCircle(); shapeMaker.drawRectangle(); shapeMaker.drawSquare(); }}

Generic:

Example:

Page 53: Design pattern

- Proxy

- Decorator

- Facade

- Adapter

- Aggregate

- Bridge

Structural Patterns

Page 54: Design pattern

Intent:

- Allows the interface of an existing class to be used as another interface

- Converts one interface to another so that it matches what the client is expecting

Application:

- Example: an adapter that converts the interface of a Document Object Model of an XML document into a tree structure that can be displayed.

Adapter Pattern (Wrapper)

Page 55: Design pattern

public interface MediaPlayer { public void play(String audioType, String fileName);}

public interface AdvancedMediaPlayer { public void playVlc(String fileName); public void playMp4(String fileName);}

public class VlcPlayer implements AdvancedMediaPlayer{ @Override public void playVlc(String fileName) {System.out.println("Playing vlc file: "+ fileName);}

@Override public void playMp4(String fileName) {// do nothing}}

public class Mp4Player implements AdvancedMediaPlayer{

@Override public void playVlc(String fileName) {// do nothing}

@Override public void playMp4(String fileName) {System.out.println("Playing mp4 file: "+ fileName);}}

Example:

Adapter Pattern

Page 56: Design pattern

public class MediaAdapter implements MediaPlayer { AdvancedMediaPlayer advancedMusicPlayer;

public MediaAdapter(String audioType) { If (audioType.equalsIgnoreCase("vlc") ) { advancedMusicPlayer = new VlcPlayer(); } else if (audioType.equalsIgnoreCase("mp4")) { advancedMusicPlayer = new Mp4Player(); } }

@Override public void play(String audioType, String fileName) { if(audioType.equalsIgnoreCase("vlc")){ advancedMusicPlayer.playVlc(fileName); } else if(audioType.equalsIgnoreCase("mp4")) { advancedMusicPlayer.playMp4(fileName); } }}

public class AudioPlayer implements MediaPlayer { MediaAdapter mediaAdapter;

@Override public void play(String audioType, String fileName) { // inbuilt support to play mp3 music files if(audioType.equalsIgnoreCase("mp3")) { System.out.println("Playing mp3 file. Name: " + fileName);

} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) { // mediaAdapter is providing support to play other file formats mediaAdapter = new MediaAdapter(audioType); mediaAdapter.play(audioType, fileName); } else { System.out.println("Invalid media. " + audioType + " format not supported"); } } }

Example:

Adapter Pattern

public class AdapterPatternDemo { public static void main(String[] args) { AudioPlayer audioPlayer = new AudioPlayer();

audioPlayer.play("mp3", "beyond the horizon.mp3"); audioPlayer.play("mp4", "alone.mp4"); audioPlayer.play("vlc", "far far away.vlc"); audioPlayer.play("avi", "mind me.avi"); }}

Page 57: Design pattern

- Proxy

- Decorator

- Facade

- Adapter

- Aggregate

- Bridge

Structural Patterns

Page 58: Design pattern

- Encapsulate what varies, OCP (Open Close Principle).

- 1 class, 1 responsability.

- Program against an interface, not an implementation, DIP.

- Prefer composition, over inheritance.

- Loose coupling, modular black boxes.

Golden OO-principles

Page 59: Design pattern

Approach:

- Understand your design context

- Examine the patterns catalogue

- Identify and study related pattern

- Apply suitable pattern

Pitfalls:

- Selectins wrong patterns

- Inappropriate use of patterns

How to choose a Pattern ?

Page 60: Design pattern

Read The Book !

Page 61: Design pattern

- Wikipedia

- tutorialspoint.com

- http://www.slideshare.net/mkruthika/software-design-patterns-ppt

- http://www.slideshare.net/HermanPeeren/design-patterns-illustrated/

- ...

Credits