0% found this document useful (0 votes)
65 views39 pages

Gang of Four

The document discusses several design patterns including Adapter, Factory Method, Singleton, Observer, and Command. It provides descriptions of when each pattern would be used, examples of their implementations, and potential issues to consider for each pattern. The Factory Method pattern creates object instances without specifying the exact class and allows for polymorphic object creation while the Observer pattern defines a subscription mechanism so that multiple objects can be notified of changes to a single object's state.

Uploaded by

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

Gang of Four

The document discusses several design patterns including Adapter, Factory Method, Singleton, Observer, and Command. It provides descriptions of when each pattern would be used, examples of their implementations, and potential issues to consider for each pattern. The Factory Method pattern creates object instances without specifying the exact class and allows for polymorphic object creation while the Observer pattern defines a subscription mechanism so that multiple objects can be notified of changes to a single object's state.

Uploaded by

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

More Design Patterns

Wednesday, 31 October 12

More Design Patterns

Wednesday, 31 October 12

1. Adapter
2. Factory Method (& Abstract Factory)
3. Singleton
4. Observer
5. Command (& Command-Holder)

1. Adapter

Wednesday, 31 October 12

problem:

you want to re-use an existing off-the-shelf


component in your design, but it doesnt quite fit
your needs

its code cannot be changed

solution:

create an Adapter class which can act as an


intermediary

Real Life Example

Wednesday, 31 October 12

problem:

a socket wrench can turn 25mm bolts (has female


25mm socket)

you want to turn a 12mm bolt (has male 12mm head)

solution:

attach a 25mm (male) to 12mm (female) adapter to


the wrench

now your wrench can turn 12mm bolts. Yay!

Coding Example: Rectangle

a LegacyRectangle takes (topLeft, topRight, width, height) as parameters


but the client wants to pass (topLeft, topRight, lowerLeft, lowerRight)
we can build an adapter (or wrapper) Rectangle class which allows this:

from http://sourcemaking.com/design_patterns/adapter

Wednesday, 31 October 12

the wrapper takes the clients request and repackages it for LegacyRectangle

How to Apply

Wednesday, 31 October 12

identify the classes which need to connect

the client and the adaptee

identify the interface which the client requires


design a wrapper class which provides the interface required
by the client:

it will have an instance of the adaptee as an attribute


it will map the client interface to the adaptee interface

the client can now use the new interface provided by the
wrapper class to access the functionality of the adaptee class.

Comment

adapter is a form of polymorphism (see Grasp Part 2)

if the component is mutable then consider changing the


code or using an interface (see polymorphism steering
example)

Wednesday, 31 October 12

adapters are used when there is an existing, immutable


component

2. Factory Method

Wednesday, 31 October 12

problem:

how do we create different kinds of subclass without:

exposing the instantiation logic to the client?


forcing the client to be aware of the different
subtypes?

solution:

we use a Factory class which creates concrete


subtypes for the client

Implementation

the client needs a new Product, so it asks the factory object for a new Product, providing
information about the type of Product it needs

the factory instantiates a new Concrete Product and returns it to the client (casted to abstract
Product class)

the client uses the Products it is given as abstract Products without being aware of their concrete
implementation

we can add more products (subtypes) without altering the clients code

from http://www.oodesign.com/factory-pattern.html

Wednesday, 31 October 12

Example: Shapes
DrawingFramewk

Shape

a graphical application:

abstract Shape class defines the draw and move operations which must be implemented by the
concrete shapes

for example, the user selects to create a circle and specifies its radius

the factory creates a new Circle and returns it to the client cast as an abstract Shape

Wednesday, 31 October 12

client: drawing framework


products: shapes

Circle

createShape( String
type, double []
parameters)

the framework receives the parameters circle and 2.5 and asks the factory to create a shape
based upon them
adapted from http://www.oodesign.com/factory-pattern.html

Abstract Factory Pattern


extends the factory method by providing the interface to create a family of related
objects without needing to explicitly refer to their classes:
uses the interfaces declared
by the AbstractFactory and
AbstractProduct classes

declares an interface for


operations which create
abstract Products

implements operations to
make concrete Products
adapted from http://www.oodesign.com/factory-pattern.html

Wednesday, 31 October 12

declares an interface for a


type of Product object

defines a Product which will be created


by the corresponding Concrete Factory
implements the AbstractProduct
interface

Implementation

Wednesday, 31 October 12

AbstractFactory:

determines the actual types of each concrete object and creates them
returns abstract pointers to the objects created

Client:

knows nothing about the actual objects creation


has no need for class declarations relating to the concrete types

Example: a global vending system:

Orders are created and need to record customers Address and


ContactPhoneNumber

those objects will have differing formats depending upon which country the
customer lives in

so we can create factories for each country (or format), and point the Order class
to the correct one based upon the customers place of residence

Issues

Wednesday, 31 October 12

Pros:

isolates creation of objects from the client, making


manipulation easier

when we need to exchange product families, the only change


we need to make in the client code is to make it use the
new factory

Cons:

adding new products to existing factories is difficult

because we have to change the AbstractFactory interface


and all its subtypes

3. Singleton

problem:

Wednesday, 31 October 12

sometimes we just want a single instance of a class


examples:

a print handler
a factory which issues unique ids to the objects which it creates

so what do we do if several clients need to be able to see a single


instance of a class and only a single instance?

solution:

we create a Singleton which provides a global and single point of


access to the class

But what is the problem?

if lots of clients need visibility to a single instance of a class, then we could just
achieve that by:

passing the reference to it around all those classes


initialise all objects which need visibility with a permanent reference

its far easier to instead provide a globally visible access point to the single instance

providing we take care to ensure its uniqueness...

which leads to one final question:

if we only need one instance of a class in our design, used by many objects, then
who should create it?

Wednesday, 31 October 12

both do-able, but very inconvenient

let it create itself!


and provide that single instance through a static getInstance() method

Example
the underlining tells us that the attribute
or method is static

MoleculeFactory
instance : MoleculeFactory
- MoleculeFactory()
+ getInstance() : MoleculeFactory

the constructor is private


so other objects can only create an

instance of this class through the publicly


visible getInstance() method

public static MoleculeFactory getInstance()


{
if ( instance == null )
{
instance = new MoleculeFactory();
}
return instance;
}

Wednesday, 31 October 12

Lazy or Eager?
Lazy Initialisation:
public static MoleculeFactory getInstance()
{
if ( instance == null )
{
instance = new MoleculeFactory();
}
return instance;
}

Wednesday, 31 October 12

Eager Initialisation
instance = new MoleculeFactory();
...
public static MoleculeFactory getInstance()
{
return instance;
}

notice that the single instance is not initialised until the getInstance method is called

this is Lazy Initialisation

why not use eager initialisation instead?


lazy initialisation is preferred because:

creation work is avoided if the instance is never actually accessed during runtime
initialisation could require complex or conditional creation logic

Use Static Methods?

why dont we just make all of the singletons methods


static and publicly visible, thus avoiding instantiation
altogether?

using a instance with non-static methods is better:

Wednesday, 31 October 12

it permits subclassing

can avoid the cannot make a static reference to the


non-static method [blah] coding error

it permits overriding, which (usually nonpolymorphic) static methods dont allow

Issues

a global access point means that the singleton is


explicitly represented by its class name at many points
in the code

if the singleton implements the Serializable interface


then it is possible to create multiple instances through
serialization then deserialization

Wednesday, 31 October 12

if we replace or rename it then every reference to it


must be replaced or renamed too

implementing readResolve() avoids this

Issues

need extra care to ensure that only one instance is


initialised if your code is multi-threaded

Wednesday, 31 October 12

use a lock. In java:

public static synchronized MoleculeFactory getInstance()

although double-locking is better

4. Observer

Wednesday, 31 October 12

problem:

a lot of objects need to know when a change


happens to another objects state

solution:

define a one-to-many dependency between objects


so that when the state of one object (the subject)
changes then all the dependant objects (the
observers) are automatically notified

But what is the problem?

Wednesday, 31 October 12

sometimes tightly coupling a lot of classes to a subject class is a bad idea:

we have to write code to explicitly update those classes whenever the


subject changes, maybe spread across several methods or classes

if more classes need to change then we have to add more code to our
program to follow any changes to the subject

not every observing class will need to update every time

so keeping a track of which classes need to update and when is


difficult

it would be better if the subject simply:

allowed other objects to subscribe to it, and then


notified its subscribers whenever its state changes

Observer Pattern
Observer
<<interface>>

public interface Observer


{
public void notify( Subject subject, Object argument);
}

notify( Subject, Object) : void

Subject
<<abstract>>
observers : ArrayList<Observer>
register( Observer) : void
unregister( Observer) : void
notifyObservers( Object) : void

Wednesday, 31 October 12

abstract class Subject


{
protected ArrayList<Observer> observers;
public void register( Observer obs)
{
observers.add( obs);
}
public void unregister( obs)
{
observers.remove( obs);
}
public void notifyObservers( Object argument)
{
Iterator iterator = observers.iterator();
while ( iterator.hasNext() )
{
Observer observer = iterator.next();
observer.notify( this, argument);
}
}
}

Example: ebay listings

whenever the current highest bid for an item ends:

Wednesday, 31 October 12

the items display listing will need to be updated


so too will the persistent record
watchers will need to be notified

by email
through their account summary

the seller, current highest bidder and previous highest bidder need to be told too
the nature and frequency of these updates will depend upon each customers
contact preferences

so, potentially a lot of conditional code to create and handle

but the observer pattern vastly simplifies this

Example: ebay listings


Subject
<<abstract>>

Item
itemId : ID
description: String
currentHighestBid: Money

observers : ArrayList<Observer>
register( Observer) : void
unregister( Observer) : void
notifyObservers( Object) : void

...
observe

DisplayListingUI
Observer
<<interface>>
notify( Subject, Object) : void

ItemsDB

Customer

Seller

...

...

...

...

...

...

...

...

when the value of currentHighestBid changes, responsibility


for which observers need to act and how is handled by the
observers themselves
Item merely tells them that its state has changed

since Item only implements an interface it can also be sub-typed


but what if we want to make Customer and Seller subtypes of User?
Wednesday, 31 October 12

Benefits

Wednesday, 31 October 12

coupling is minimised:

the subject doesnt know anything about its observers


only that it has a list of observers
the observers dont know about each other
but behave as if they do
when one changes, so does another
so we achieve abstract, minimised coupling

Benefits

Wednesday, 31 October 12

updates can be broadcast:

when the subject changes it notifies all observers


without needing to specify each receiver
and we can add or remove as many observers as we like

reactions can be conditional:

observers get to choose which notifications to respond


to, how to respond and which to ignore

in the ebay example this can be on an object-by-object


basis for the customer class

Problems

Wednesday, 31 October 12

timing issues:

in a multi-threaded program observers might update


out of desired order

for example, web page says item in stock before the


database gets updated

we might accidentally notify observers before we have


finished updating the subject (easier to do than youd
think)

without care we could also cause recursive notifications

Problems

Wednesday, 31 October 12

performance issues:

an update could cause a cascade of notifications (especially


where some observers are also subjects for their own sets of
observers)

we can mitigate this by allowing observers to register to


specific events within the subject

subject is an abstract class, not an interface:

java wont allow multiple (abstract) inheritance


if your subject must be a sub-type of another class then youll
need to explicitly code the Subject methods and list of
observers into it

Problems

who should call notifyObservers()?

Wednesday, 31 October 12

it could be a private method, called by the subject


but that could be inefficient

for example: multiple successive changes happen


to the subjects state

we could let clients call the method instead


but that makes errors more likely

5. Command

Wednesday, 31 October 12

problem:

one class in the user interface is usually responsible for


listening to user actions

it often also becomes the repository for all the logic which
responds to user actions

this leads to large, incohesive classes


it violates the principle of separation of concerns

solution:

assign responsibility for the responses to small, functionally


distinct Command classes

Command Interface
public interface Command
{
public void execute();
}

all the working code resides within, or is called from, the


execute() method

this presents a common interface to clients, reducing the


need for conditional handling of different methods for
different objects

Wednesday, 31 October 12

Example: Control Buttons


start

pause

resume

without using Command:

using Command:

inside the main UI class:

inside the main UI class:

public void ActionPerformed( Event event)


{
if ( event.getSource.equals( startButton) )
{
simulation.start();
}
else if ( event.getSource.equals( pauseButton) )
{
simulation.pause();
}
else if ( event.getSource.equals( resumeButton) )
{
simulation.resume();
}
.... // and so on for all other UI events
}

public void ActionPerformed( Event event)


{
((Command) event.getSource()).execute();
}

Wednesday, 31 October 12

inside a typical button class:


public StartButton extends JButton implements Command
{
public void execute()
{
simulation.start();
}
}

...better, but still problems

Wednesday, 31 October 12

we have separated the details of the commands from the main


UI

but they are still tightly coupled to the individual UI


components which trigger them

and we might want to trigger a command from multiple


components

or even from some other source (e.g. control code)


we might want to alter the command triggered by a
component

so we should use the CommandHolder interface

CommandHolder Interface
public interface CommandHolder
{
public void setCommand( Command command);
public Command getCommand();
}

all the working code now resides within separate Command classes

when a client requests a Command from a CommandHolder using


getCommand(), the CommandHolder simply passes the Command to
the client

the CommandHolder classes (usually UI components) only need to


know that they hold a Command, not what it does

Wednesday, 31 October 12

Example: Control Buttons


start

pause

resume

using CommandHolder:
inside the main UI class:

typical Command class:

public void ActionPerformed( Event event)


{
((Command) event.getSource().getCommand()).execute();
}

public StartCommand implements Command


{
public void execute()
{
simulation.start();
}
}

typical button class:


public StartButton extends JButton implements CommandHolder
{
Command myCommand;
public void setCommand( Command command)
{
this.command = command;
}
public Command getCommand()
{
return Command;
}
}
Wednesday, 31 October 12

and because we can easily swap the


command held by a button, we have the
opportunity to replace the three buttons
with one, de-cluttering the user interface

Benefits

application logic fully separated from the UI


allows contextual use of components:

can switch the commands which they invoke, even


disable them

allows commands to be maintained and invoked away


from the UI

if we record the list of commands so far invoked then


we can often implement an Undo command

Wednesday, 31 October 12

To conclude

the five (and a bit) patterns investigated here build upon the core
GRASP principles

taken together they can lead to clean, cohesive, lightly coupled code

Wednesday, 31 October 12

easy to read
easy to re-use
easy to change

you can create your own java libraries for some of the interfaces
as always, use appropriately

some small, one-off projects wont need this degree of flexibility

References & Further Reading

Wednesday, 31 October 12

Adapter

http://sourcemaking.com/design_patterns/adapter

Factory Method

http://www.oodesign.com/factory-pattern.html
http://www.oodesign.com/abstract-factory-pattern.html

Singleton

http://www.ibm.com/developerworks/java/library/j-dcl/index.html

Observer Pattern

http://www.research.ibm.com/designpatterns/example.htm

Command Holder

Java Design Patterns: A Tutorial (JW Cooper 2000)

You might also like