0% found this document useful (0 votes)
340 views36 pages

7.GoF Design Patterns

The document discusses several Gang of Four (GoF) design patterns including the Adapter, Factory, and Singleton patterns. It describes how the Adapter pattern allows incompatible interfaces to work together through an intermediate adapter object, how the Factory pattern handles object creation responsibilities, and how the Singleton pattern ensures only one instance of a class can exist. It also shows how these patterns can be applied together in software designs.

Uploaded by

Karthik Sara M
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
340 views36 pages

7.GoF Design Patterns

The document discusses several Gang of Four (GoF) design patterns including the Adapter, Factory, and Singleton patterns. It describes how the Adapter pattern allows incompatible interfaces to work together through an intermediate adapter object, how the Factory pattern handles object creation responsibilities, and how the Singleton pattern ensures only one instance of a class can exist. It also shows how these patterns can be applied together in software designs.

Uploaded by

Karthik Sara M
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 36

GoF Design Patterns

GoF Design Patterns


“Gang of Four” Design Patterns
• Adapter
• Factory
• Singleton
• Observer (Publish-Subscribe)
Adapter Pattern
Problem: How to resolve incompatible interfaces,
or how to provide a stable interface to similar
components with different interfaces.

Solution: Convert the original interface of a


component into another interface, through an
intermediate adapter object.

Note: the Adapter pattern is an application of


Polymorphism
Adapter Pattern
Example: POS needs to adapt several kinds
of external third-party services: tax
calculators, credit authorization services,
inventory systems, accounting systems.
Each has a different API which can’t be
changed.
«interface» Adapters use interfaces and
ITaxCalculatorAdapter polymorphism to add a level of
indirection to varying APIs in other
getTaxes( Sale ) : List of TaxLineItems components.

TaxMasterAdapter GoodAsGoldTaxPro
Adapter

getTaxes( Sale ) : List of TaxLineItems


getTaxes( Sale ) : List of TaxLineItems

«interface» «interface»
IAccountingAdapter ICreditAuthorizationService
Adapter
postReceivable( CreditPayment )
postSale( Sale ) requestApproval(CreditPayment,TerminalID, MerchantID)
... ...

«interface»
IInventoryAdapter
SAPAccountingAdapter GreatNorthernAccountingAdapter
...

postReceivable( CreditPayment ) postReceivable( CreditPayment )


postSale( Sale ) postSale( Sale )
... ...
:Register : SAPAccountingAdapter

makePayment
...
SOAP over
HTTP

postSale( sale )
xxx «actor»
: SAPSystem

the Adapter adapts to


interfaces in other components
Adapter Pattern
Note: Adapter pattern follows GRASP
principles: Polymorphism, Protected
Variation, Indirection

conceptual connection among GRASP


principles and Adapter pattern
Conceptual connection among GRASP principles and Adapter
pattern

Low coupling is a way to achieve protection at a Protected Variation GRASP


variation point. Mechanism Principles

Polymorphism is a way to achieve protection at a


variation point, and a way to achieve low coupling.

An indirection is a way to achieve low coupling. Low Coupling High Cohesion


Mechanism Mechanism
The Adapter design pattern is a kind of Indirection
and a Pure Fabrication, that uses Polymorphism.

Polymorphism Indirection Pure


Example Mechanism Fabrication

GoF Design
Adapter Patterns
Factory Pattern
Problem: Who should be responsible for
creating objects when there are special
considerations such as complex creation
logic, a desire to separate creation
responsibilities for better cohesion, etc.?

Solution: Create a Pure Fabrication object


called a Factory that handles the creation.
Factory Pattern
• Technically not a GoF pattern
• A variation of GoF Abstract Factory
pattern
Fig. 26.5
ServicesFactory note that the factory methods
return objects typed to an
accountingAdapter : IAccountingAdapter interface rather than a class, so
inventoryAdapter : IInventoryAdapter that the factory can return any
taxCalculatorAdapter : ITaxCalculatorAdapter implementation of the interface

getAccountingAdapter() : IAccountingAdapter
getInventoryAdapter() : IInventoryAdapter
getTaxCalculatorAdapter() : ITaxCalculatorAdapter
...

if ( taxCalculatorAdapter == null )
{
// a reflective or data-driven approach to finding the right class: read it from an
// external property

String className = System.getProperty( "taxcalculator.class.name" );


taxCalculatorAdapter = (ITaxCalculatorAdapter) Class.forName( className ).newInstance();

}
return taxCalculatorAdapter;
Factory Pattern (26.4)
Note: In Fig. 26.5 the implementation of
ServicesFactory illustrates data-driven
design – a form of Protected Variation
Factory Pattern (26.4)
Idea: Define an object whose purpose is to
create objects

Benefits:
– Separate the responsibility of complex
creation into cohesive helper objects
– Can provide object caching (e.g. having only
one random number generator)
Singleton Pattern (26.5)
Problem: Exactly one instance of a class is
allowed. Objects need a global and single
point of access.

Solution: Define a static method of the


class that returns the singleton:
getInstance()
Singleton Pattern (26.5)
Consider the factory and how it is accessed – who creates
the factory?
– Only want one instance of the factory
– Methods may need to be called from various places => how to
make single instance of the factory globally visible

Could pass the ServicesFactory instance around as a


parameter whenever visibility is required or initialize all
objects that need it with a permanent reference to it

Singleton – supports global visibility or a single access


point to a single instance
Fig. 26.6
UML notation: this '1' can optionally be used to
indicate that only one instance will be created (a
singleton)

1
ServicesFactory

UML notation: in a instance : ServicesFactory singleton static


class box, an attribute
underlined attribute or accountingAdapter : IAccountingAdapter
method indicates a inventoryAdapter : IInventoryAdapter
static (class level) taxCalculatorAdapter : ITaxCalculatorAdapter
member, rather than singleton
an instance member getInstance() : ServicesFactory static
method
getAccountingAdapter() : IAccountingAdapter
getInventoryAdapter() : IInventoryAdapter
getTaxCalculatorAdapter() : ITaxCalculatorAdapter
...

// static method
public static synchronized ServicesFactory getInstance()
{
if ( instance == null )
instance = new ServicesFactory()
return instance
}
Singleton Pattern (26.5)
Note: concurrency control in
ServicesFactory – making getInstance()
synchronized

Fig. 26.8 shows how Adapter, Factory,


Singleton patterns are used in design
Fig. 26.8 1
:Store
:ServicesFactory

create
create :Register

accountingAdapter =
getAccountingAdapter
create : SAPAccounting
Adapter

accountingAdapter:
:Register
SAPAccountingAdapter

makePayment
create(cashTendered) : Payment SOAP over
HTTP

postSale( sale )
xxx «actor»
: SAPSystem
Observer Pattern (26.10)
Also known as Publish-Subscribe Pattern

Problem: Different kinds of subscriber objects are


interested in state changes or events of a publisher
object and want to react in their own unique way when
the publisher generates an event. The publisher wants
to maintain low coupling to the subscribers.

Solution: Define a subscriber or listener interface.


Subscribers implement the interface. The publisher can
dynamically register subscribers who are interested in an
event and notify them when an event occurs.
Observer Pattern (26.10)
Example: Want a GUI window to refresh
(update) its display of sale total when the
total changes
See Fig. 26.21
Fig. 26.21

Goal: When the total of the sale


changes, refresh the display with
the new value

Sale

total
...

setTotal( newTotal )
...
Observer Pattern (26.10)
Example (cont):
Simple solution – when Sale changes its
total the object sends a message to the
window telling it to refresh its display

Problem – high coupling between domain


objects and UI objects
Observer Pattern (26.10)
Example (cont):
Want to be able to easily replace UI
objects or even add other UI objects that
can be notified of this event

That is, want model-view separation


Model objects shouldn’t know about view
objects => Protected Variations with
respect to a changing user interface
Fig. 26.22
{ {
for each PropertyListener pl in propertyListeners propertyListeners.add( lis );
pl.onPropertyEvent( this, name, value ); }
}

Sale

addPropertyListener( PropertyListener lis )


publishPropertyEvent( name, value )

setTotal( Money newTotal )


...
{
total = newTotal;
publishPropertyEvent( "sale.total", total );
}

javax.swing.JFrame propertyListeners
*
... «interface»
setTitle() PropertyListener
setVisible()
... onPropertyEvent( source, name, value )

{
if ( name.equals("sale.total") )
saleTextField.setText( value.toString() );
}
SaleFrame1

onPropertyEvent( source, name, value ) {


sale.addPropertyListener( this )
initialize( Sale sale ) ...
... }
Observer Pattern (26.10)
Steps (p. 465)
1. Define an interface PropertyListener with operation
onPropertyEvent
2. Define window (SaleFrame1) to implement the interface
3. When SaleFrame1 is initialized pass it the Sale instance from
which it is displaying the total
4. SaleFrame1 registers to the Sale instance for notification of
“property events” via the addPropertyListener message
5. Note that the Sale does not know about SaleFrame1 objects; it
only knows about objects that implement the PropertyListener
interface. (This lowers the coupling of the Sale to the window
– the coupling is only to an interface, not to a GUI class.)
6. The Sale instance is the publisher of “property events”. When
the total changes, it iterates across all subscribing
PropertyListeners, notifying each
Observer Pattern (26.10)
Notes:
– The SaleFrame1 object is the
observer/subscriber/listener
– Sale is the publisher of property events
– Sale adds SaleFrame1 object to its list of
PropertyListener subscribers – Fig. 26.23
Fig. 26.23

sf : SaleFrame1 propertyListeners :
s : Sale
List<PropertyListener>

initialize( s : Sale )

addPropertyListener( sf )
add( sf )
Observer Pattern (26.10)
Notes:
– When the Sale total changes it iterates over
all registered subscribers and sends the
onPropertyEvent message to each – Figs.
26.24, 26.25
Fig. 26.24

s :Sale propertylisteners[ i ] :
PropertyListener

setTotal( total )
publishPropertyEvent
( "sale.total", total )

loop onPropertyEvent( s, "sale.total", total )


Fig. 26.25

Since this is a polymorphic operation implemented by


this class, show a new interaction diagram that starts saleTextField
: SaleFrame1
with this polymorphic version : JTextField

onPropertyEvent( source, name, value )

setText( value.toString() )

UML notation: Note this little expression within the


parameter. This is legal and consise.
Fig. 26.26
Sale

addPropertyListener( PropertyListener lis )  publishes events to


publishPropertyEvent( name, value ) observers/listeners/
subscribers
setTotal( Money newTotal )  registers them when
... they ask to subscribe

javax.swing.JFrame propertyListeners
*
... «interface»
setTitle() PropertyListener
setVisible()
... onPropertyEvent( source, name, value )

 listens for events


SaleFrame1  observes events
 subscribes to notification of events
onPropertyEvent( source, name, value )

initialize( Sale sale )


...

Who is the observer, listener, subscriber, and publisher?


Observer Pattern (26.10)
Notes:
– Sale is coupled to view object but only loosely since it
only knows subscribers as implementing the
PropertyListener interface
– In Java this was called Delegation Event Model

Observer pattern is basis for GUI widget event


handling in both Java (AWT & Swing) and .NET
Widgets are publishers of events, other objects
can register as listeners
Observer Pattern (26.10)
Example of AlarmClock:
AlarmClock is publisher of alarm events

Different types of objects can register as


listeners and react to same alarm event in
their own ways
Fig. 26.27
{
for each AlarmListener al in alarmListeners
al.onAlarmEvent( this, time );
} {
alarmListeners.add( lis );
}
AlarmClock

addAlarmnListener( AlarmListener lis )


publishAlarmEvent( time )

setTime( newTime ) {
... time = newTime;
if ( time == alarmTime )
publishAlarmEvent( time );
}
javax.swing.JFrame alarmListeners
*
... «interface»
setTitle() AlarmListener
setVisible()
... onAlarmEvent( source, time )

AlarmWindow Beeper ReliabilityWatchDog

onAlarmEvent( source, time ) onAlarmEvent( source, time ) onAlarmEvent( source, time )


... ... ...

{ {
{
display notification dialog check that all required processes
beep
box are executing normally
}
} }
Summary
• Singleton:
– Factory for a singular (sole) instance
– Ensures that only one object of a particular class is
ever created.
• Adapter:
– Translator adapts a server interface for a client
– Used to provide link between two or incompatible
types by wrapping with a class that supports the
interface required by the client.
Observer Pattern:
– Used to allow an object to publish changes to its
state.
– Other objects subscribe to be immediately notified
of any changes.
– Dependents update automatically when subject
changes
• Factory:

– Factory for building related objects

– Used to provide client with a set of related and


dependent objects.

You might also like