1
Design Pattern
Elements of a Design Pattern 2
A pattern has four essential elements (GoF)
Name
Describes the pattern
Adds to common terminology for facilitating communication (i.e.
not just sentence enhancers)
Problem
Describes when to apply the pattern
Answers - What is the pattern trying to solve?
Elements of a Design Pattern 3
(cont.)
Solution
Describes elements, relationships, responsibilities, and
collaborations which make up the design
Consequences
Results of applying the pattern
Benefits and Costs
Subjective depending on concrete scenarios
Design Patterns Classification 4
A Pattern can be classified as
Creational
Structural
Behavioral
Design Patterns Classification 5
(Cont)
Creational patterns deals with object creation. Class scope creational
patterns defer some part of the object creation process to subclasses. Object
scope creational patterns defer it to another object.
Structural patterns deals with compositions of objects and classes.
Structural class patterns are based on inheritance to build a structure.
Structural object patterns use object references to build a structure.
Behavioural patterns are used to distribute responsibility between classes
and objects. The patterns define how the classes and objects should interact,
and what responsibilities each participant has. Behavioural class patterns are
based on inheritance. They are mostly concerned with handling algorithms
and flow of control. Behavioural object patterns describe how objects can
cooperate to carry out tasks that no single object can carry out alone.
Total 23 design patterns 6
Singleton Pattern 7
Intent: Ensure a class only has one instance, and provide a global point of
access to it.
Motivation: The reason behind is
More than one instance will result in incorrect program behaviour. (thread
specific)
More than one instance will result the overuse of resources. (ex: database
connection string)
Some classes should have only one instance throughout the system for (ex:
printer spooler)
Classification: Classified as one of the most known Creational Pattern
Singleton Pattern
8
public class Singleton{
private static Singleton singleInstance;
private Singleton(){
//nothing to do as object initiation will be done once
}
public static Singleton getInstance(){
if(singleInstance == null){
singleInstance = new Singletong(); // Lazy instance
}
return singleInstance;
}
}
Singleton Pattern
9
public class Singleton{
private static Singleton singleInstance;
private Singleton(){
//nothing to do as object initiation will be done once
}
public static Singleton getInstance(){
if(singleInstance == null){
singleInstance = new Singletong(); // Lazy instance
}
return singleInstance;
}
}
From main method call –
Singleton instance = Singleton.getInstance();
Singleton 10
Participants:
Singleton-defines an Instance operation that lets clients access its unique
instance. Instance is a class operation .It may be responsible for creating its
own unique instance. (ex: Singleton)
Structure:
Singleton 11
Lazy instance: Singleton make use of lazy initiation of the
class. It means that its creation is deferred until it is first used.
It helps to improve performance, avoid wasteful computation
and reduce program memory requirement.
Adapter Pattern 12
In the real world...
we are very familiar with adapters and what they do
What about object oriented adapters?
13
Intent:
Convert the interface of a class into another interface clients expect.
Adapter lets classes work together that couldn't otherwise because of
incompatible interfaces.
Classified as:
A Structural Pattern
(Structural patterns are concerned with how classes and objects are
composed to form larger structures.)
Also Known As:
Wrapper
Adapter Pattern 14
Adapter pattern can be solved in one of two ways:
Class Adapter: in this case, as it implements the adaptee, only can
override the adaptee’s methods. It can not adapt the adaptee’s subclasses.
Object Adapter: It can adapt the subclasses as well. However, can not
override any behaviour of adaptee.
Class Adapter 15
Scenario: I have a pizza making store that creates different pizzas based on
the choices of people of different locations. For example – people of Dhaka
like DhakaStylePizza, people of Sylhet like SylhetStylePizza.
Class Adapter 16
Scenario: I have a pizza making store that creates different pizzas based on
the choices of people of different locations. For example – people of Dhaka
like DhakaStylePizza, people of Sylhet like SylhetStylePizza.
Solution: To meet the scenario, we can declare a Pizza interface and different
location people can make their own style pizza by implementing the same
interface.
Class Adapter 17
Public Interface Pizza{ Public class DhakaStylePizza implements
abstract void toppings(); Pizza{
abstract void bun(); public void toppings(){
} print(“Dhaka chesse toppings”);
}
public void bun(){
print(“Dhaka bread bun”);
}
}
Class Adapter 18
Now we want to support ChittagongStylePizza and hence already found an
existing class doing so in a different way.
public class ChittagongPizza{
public void sausage(){
print(“Ctg pizza”);
}
public void bread(){
print(“Ctg bread”);
}
}
Class Adapter 19
We want to adapt the existing ChittagongPizza
To do so, introduce a Class Adapater, ChittagongStylePizzaClassAdapter
Class Adapter 20
We want to adapt the existing ChittagongPizza
To do so, introduce a Class Adapater, ChittagongStylePizzaClassAdapter
Public class ChittagongStylePizzaClassAdapter extends ChittagongPizza implements Pizza{
public void toppings(){
this.sausage();
}
public void bun(){
this.bread();
}
}
Class Adapter 21
We want to adapt the existing ChittagongPizza
To do so, introduce a Class Adapater, ChittagongStylePizzaClassAdapter
Public class ChittagongStylePizzaClassAdapter extends ChittagongPizza implements Pizza{
public void toppings(){
this.sausage();
}
public void bun(){
this.bread();
}
} main method call –
From
Pizza adaptedPizza = new ChittagongStylePizzaClassAdapter();
adaptedPizza.toppings();
adaptedPizza.bun();
Adapter Pattern 22
Participants:
Target: defines the domain-specific interface that Client uses. (ex: Pizza)
Client: collaborates with objects conforming to the Target interface.
Adaptee: defines an existing interface that needs adapting (ex:
ChittagongPizza)
Adapter: adapts the interface of Adaptee to the Target interface. (ex:
ChittagongStylePizzaClassAdapter)
Adapter Pattern 23
Structure:
Object Adapter 24
Now, create a object adapter for adapting the same ChittagongPizza existing
class.
public class ChittagongStylePizzaObjectAdapter implements Pizza{
private ChittagongPizza ctgPizza;
public ChittagongStylePizzaObjectAdapter(){
ctgPizza = new ChittagongPizza();
}
public void toppings(){
ctgPizza.sausage();
}
public void bun(){
ctgPizza.bread();
}
}
Observer Pattern 25
Intent: Define a one-to-many dependency between objects so that when oneobject
change state, all its dependents are notified and updated automatically.
Observer Pattern 26
public class Celebrity{
private List<Fan> fans = new ArrayList<Fan>();
private int state;
void attach(Fan f){
fans.add(f);
}
void remove(Fan f){
fans.remove(f); Celebrity class may look like this.
}
void notify(){
foreach( Fan f: fans)
f.update(this);
}
void setState(int newState){
state = newState;
notify();
}
int getState(){
return state;
}
}
Observer Pattern 27
public class Celebrity{
private List<Fan> fans = new ArrayList<Fan>();
private int state;
void attach(Fan f){
fans.add(f);
}
void remove(Fan f){
fans.remove(f); Celebrity class may look like this.
}
void notify(){
Now add the Fan class
foreach( Fan f: fans)
f.update(this);
}
void setState(int newState){
state = newState;
notify();
}
int getState(){
return state;
}
}
Observer Pattern 28
public class Celebrity{
private List<Fan> fans = new ArrayList<Fan>();
private int state; public class Fan{
void attach(Fan f){ private List<Celebrity> celebrities= new
fans.add(f); ArrayList<Celebrity>();
}
void remove(Fan f){ void update(Celebrity c){
fans.remove(f); c.getState();
} }
void notify(){ void addCelebrity(Celebrity c){
foreach( Fan f: fans) celebrities.add(c);
f.update(this);
} c.attach(this);
void setState(int newState){ }
state = newState; void removeCelebrity(Celebrity c){
notify(); celebrities.remove(c);
} c.remove(this);
int getState(){
return state; }
}
}
}
Observer Pattern 29
From main method –
Fan f1 = new Fan();
Fan f2 = new Fan();
Celebrity c1 = new Celebrity ();
Celebrity c2 = new Celebrity ();
f1.addCelebrity(c1);
f1.addCelebrity(c2);
f2.addCelebrity (c1);
c1.setState(5); //new State
c2.setState(2); //newState
Participants 30
Subject: knows its observers. Any number of Observer objects may
observe a subject. It sends a notification to its observers when its state
changes. (ex: Celebrity)
Observer: defines an updating interface for objects that should be
notified changes in a subject. (ex: Fans)
ConcreteSubject: (ex: FilmCelebrity, FashionCelebrity)
ConcreteObserver (ex: FilmFan, FashsionFan)
Structure 31
Advanced Observer with Concrete subjects and 32
observers
Public FilmCelebrity extends Celebrity{
private int state;
void setState(int newState){
state = newState;
notify();
}
int getState(){
return state;
}
}
Advanced Observer with Concrete subjects and 33
observers
Public FilmCelebrity extends Celebrity{public class FilmFan extends Fan{
private int state; private List<FilmCelebrity> filmCelebrities= new
void setState(int newState){ ArrayList<FilmCelebrity>();
state = newState; void update(FilmCelebrity fc){
notify(); if(filmCelebrities.contain(fc){
} fc.getState();
int getState(){ }
return state; }
} void addCelebrity(FilmCelebrity fc){
} celebrities.add(fc);
fc.attach(this);
}
void removeCelebrity(FilmCelebrity fc){
celebrities.remove(fc);
fc.remove(this);
}