Michael Brockway
Advanced Applications Development in Java
Design Patterns
IntroductionWhat is a pattern?Design Patterns -- definitionsExamples
Introduction to Design Patterns 2
Introduction Developers never solve every problem
from first principles We re-use old solutions which have worked,
adapting them to the new situation. We re-use successful designs by basing any
new design on prior experience.
A bit of history The idea originated with a building architect,
Christopher Alexander in the 1970s who applied it to architecture and urban planning in 1970s
In 1987, Ward Cunningham and Kent Beck devised five patterns for the guidance of Smalltalk (an early OO language) programmers
A programming problem could be solved by finding which of the patterns best matches the problem, and using this pattern to “cut” a solution
Around 1990, Jim Coplien began collecting C++ idioms for use as patterns to guide programmers
Design Patterns grew in 1990-94 from these beginings
Introduction to Design Patterns 3
Introduction
What do we mean by a pattern? “an abstraction from a concrete form which
keeps recurring in vrious specific contexts” It captures the essence of many approaches to a
design problem: what is the “right” approach
Design Patterns Simple, elegant, flexible solutions to specific
problems. Solutions have evolved over time Not always obvious -- result from hard work +
sharing and evaluating of ideas An insight into flexible, modular, re-usable
design The “bible” is Design Patterns, by Erich
Gamma, Richard Helm, Ralph Johnson & John Vlissides et al, Addison-Wesley, 1995, ISBN 0201633612
op Read Bennett, McRobb & Farmer, Object Oriented Systems Analysis & Design using UML, chapter 14.
Introduction to Design Patterns 4
What is a Pattern?
So what exactly is a software design pattern? There are 4 essential elements of a design pattern: the Pattern Name the Problem
This describes when the pattern can be applied: to what kind of problem, and what pre-conditions need to be met to apply it
the Solution A template or abstract description of the
problem solution in terms of a set of classes (objects) with particular functionalities and interrelationships
Consequences presenting the results and tradeoffs of using the
pattern, helping you decide the best choice from among several promising alternatives.
Introduction to Design Patterns 5
Design Patterns
Additional information might include concrete, detailed examples of use
There are many design patterns, catalogued for easy navigation and comparison:
Some Design Patterns - Structural Patterns
Composition of classes/objects Example: the Adapter pattern converts the
interface of a class into another interface clients expect.
Example: the Composite pattern composes objects into tree-structures to represent part/whole relationships and lets clients treat individuals and groups uniformly.
Example: the Decorator pattern attaches additional responsibility to an object dynamically -- more flexibly than subclassing.
Introduction to Design Patterns 6
Design Patterns Creational patterns
The process of object construction Example: the Singleton pattern is for a class that
has only one instance Example: the Abstract Factory pattern provides
an interface for creating families of related or dependent objects without specifying their concrete class.
Example: the Factory Method pattern defines an interface for creating an object of some class but defers instantiation to subclasses
Behavioural Patterns The way classes and objects interact Example: the Iterator pattern provides an
interface for accessing elements of an aggregate, such as a vector or a list, without exposing the aggregates interface or internal structure.
Introduction to Design Patterns 7
Design Patterns Behavioural Patterns ctd
Example: the Observer pattern defines a 1 to many dependency between objects so that when one changes state, all dependents are notified and updated.
Example: the Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable: the functinality of an object can be varied by plugging in a different one.
Example: the Template Method pattern defines the skeleton of an algorithm in an operation (function), deferring some steps to a subclass; multiple subclasses redefine certain steps of the algorithm without changing the algorithm’s structure.
Example: the State pattern allows an object to alter its behaviour when its internal state changes. The object will appear to change its class.
Example: the Command pattern encapsulates a request as an object, so we can parameterize clients with different requests, queue/log requests, support undoable operations.
Introduction to Design Patterns 8
Example:
Composite Design Pattern
A group of objects where An object can be an individual or a group of
objects Individuals and groups are to be treated the
same way.
...
0..1
1..*aggregation<<abstract>>
Component
op1();
possibly an interface
several ops
Composite
op1( );addChild( )
removeChild( )
Leaf
op1( );for each child g,
g.op1();
possibly other methods for managing children
Introduction to Design Patterns 9
Example:
Composite Design Pattern
Component interface Specifies the interface common to all objects
in the composition
Leaf classes (several different, in general) Each implements Component and and defines
behaviours for primitive objects in the composition. These objects have no children.
Composite class Implements Component and defines
behaviours for components with children. Normally this will consists of iterating through the children, performing the behaviour with each child.
Introduction to Design Patterns 10
Example:
Composite Design Pattern
Example of using this A Drawing is group -- an aggregate of Shape
objects A Shape is a Rectangle or an Oval or a Circle
or a Line or group of shapes Derive Rectangle, Oval, Line, Circle, from
abstract base class Shape We want a group of shape elements to be
handled (positioning, resizing, ...) in the same way as individual shape elements
A Drawing is just such a group -- so derive it from Shape too:
Shape
Rectangle Line DrawingCircle
0..1
1..*aggregation
Oval
Introduction to Design Patterns 11
Composite Design Pattern applied to
Shapes A Shape is associated with 0 or 1 Drawing A Drawing contains one or more Shapes
...which may recursively be individual Rectangles, Ovals etc, or Drawings, ie groups
At the moment, we have four “leaf” subclasses. Common Shape operations (“op1()”) will be
declared abstract in Shape and implemented in the subclasses.
Drawing subclass additionally needs addChild, removeChild() children management methods
The Java implementation MyShape.java is the abstract base class
listing attached to these notes MyOval.java, MyCircle are a typical “leaf”
classes listings attached to these notes
MyRectangle.java, MyLine.java More “leaf” classes: you are asked to write these
in the practical exercise
Introduction to Design Patterns 12
Composite Design Pattern applied to
Shapes The Java implementation of the
“composite” class, MyDrawing.java. It is derived from MyShape:public class MyDrawing extends MyShape {
It needs a way of storing its children:Vector children = new Vector();
Constructor is similar to the others’ -- but width and height are 0:
public MyDrawing(int x, int y) {
super(x, y, 0, 0);
}
It has methods for adding and removing a shape:
public void add(MyShape s) {
children.addElement(s);
}
public void remove(MyShape s) {
children.removeElement(s);
}
Introduction to Design Patterns 13
Composite Design Pattern applied to
Shapes
The Java implementation of the “composite” class Re-sizing is not allowed for Drawings:public void size(int wdth, int hgt) {
throw new
UnsupportedOperationException();
}
You move a Drawing by moving all the shapes it contains:
public void move(int x, int y) {
int dx = x - getX();
int dy = y - getY();
Iterator it = children.iterator();
while(it.hasNext()) {
MyShape s = (MyShape)it.next();
int newX = s.getX() + dx;
int newY = s.getY() + dy;
s.move(newX, newY);
}
}
NB Vectors and Iterators live in java.util.* Likewise, draw a Drawing by delegating:
Introduction to Design Patterns 14
Composite Design Pattern applied to
Shapes
The Java implementation of the “composite” class Likewise, draw a Drawing by delegating:public void draw(Graphics g) {
Iterator it = children.iterator();
while(it.hasNext()) {
MyShape s = (MyShape)it.next();
s.draw(g);
}
}
Using the composite Pattern
Introduction to Design Patterns 15
Using Composite Pattern
We start with a drawingprivate MyDrawing shapes =new MyDrawing(0,0);
That we populate with shapesshapes.add(new MyRectangle(13,25,100,200));shapes.add(new MyCircle(110,150,100));shapes.add(new MyRectangle(10,50,200,200));
That can be drawingsprivate MyDrawing blob = new MyDrawing(30,20);shapes.add(blob);blob.add(new MyRectangle(13,25,100,200));blob.add(new MyCircle(110,150,100));
We can then move parts blob.move(30,15);
Or the whole shapes.move(10,15);
And draw it all to a graphics object shapes.draw(g);
Introduction to Design Patterns 16
Using Composite Pattern
An Advantage of Polymorphism: Adding a new shape requires no
modification of existing code 1. Derive the new shape from
MyShape overriding the draw method 2. That’s it. All code that uses MyShape will work
with the new shape. Alternative designs can use type
information explicitly e.g. instanceof() These are likely to require additional
modifications You have to take care with the use of
run time type information Avoid “switch on type” constructs.
Introduction to Design Patterns 17
Example: Adapter Pattern
Converts the interface of a class into another interface clients expect.
Note the two versions: object version and class version Target interface specifies the interface that Client expects Adaptee is a class that provides desired functionality but
an interface need to be adapted to Target Adapter provides adapted interface either by subclassing
or by “owning” an Adaptee object.
<<interface>>Target
AdapteeClassAdapterClass
Client
<<interface>>Target AdapteeClass
AdapterClass
Client
Introduction to Design Patterns 18
Example: Adapter Pattern
Drawing Editor
Shape
boundingBox()createManipularor()
TextShape
boundingBox()createManipularor()
TextView
getExtent()
Line
boundingBox()createManipularor()
return text.getExtent()
return new TextManipulator
Ref: Gamma et al p 139 fff
Introduction to Design Patterns 19
Example: Factory Method Pattern
Defines an interface for creating an object of some class but defers instantiation to subclasses
Abstract Creator class specifies factory method ConcreteCreator class -- several of these -- each extends
Creator and implements its factory method createProduct Product interface -- the interface of objects created by the
factory method ConcreteProduct classes -- several -- implement the
interface. Objects created by the factory method are instances of these classes.
<<interface>>Product
ConcreteCreatorcreateProductl( ) : ConcreteProductop()
ConcreteProduct
...return new ConcreteProduct();
<<abstract>>Creator
createProduct( ):op();
product
Introduction to Design Patterns 20
Example: Factory Method Pattern
Ref: Gamma et al p 107
Application
createDocument( ):newDocment();openDocument….
MyApplication
createDocumentl( ) : MyDocument
MyDocument
...return new MyDocument();
Document
open()close()save()revert()
docs
Document doc = createDocument()docs.add(doc);doc.open();
Introduction to Design Patterns 21
Example: Iterator Pattern
Iterator interface specifies operations for accessing a given category of collections
ConcreteIterator class implements Iterator interface. Each object keeps track of its current position in the traversal of the underlying aggregate.
Aggregate interface specifies operations for aggregates, which must include an operation for returning an Iterator.
ConcreteAggregate class implements this -- could be Vector or Collection or user defined, based on these or an array
Client interacts with a ConcreteAggregate through the Iterator interface.
We have already made soome use of this pattern!
<<interface>>
Aggregate
getIterator();
<<interface>>
Iterator
next():Object;hasNext(): boolean
Client
ConcreteIterator
next():Object;hasNext(): boolean
ConcreteAggregate
getIterator(): Iterator
1 *
Introduction to Design Patterns 22
Example: Iterator Pattern
See Java util package documentation. Iterator is intended as a replacement for Enumeration (which has simlar abstract methods hasMoreElements(), nextElement(); a Vector also has a method elements() which returns an object of anonymous class implementing Enumeration )
Java.util.Collection
iterator();
Java.util.
Iterator
next():Object;hasNext(): boolean
(anon class)
next():Object;hasNext(): boolean
Vector
iterator(): Iterator
Introduction to Design Patterns 23
Example: Template Method Pattern
Defines the skeleton of an algorithm in an operation (function), deferring some steps to a subclass; multiple subclasses redefine certain steps of the algorithm without changing the algorithm’s structure.
AbstractClass specifies one or more template methods that implement a partially complete algorithm and specify abstract hook methods that the template mwthod(s) will use.
ConcreteClass extends AbstractClass, implementing the hook methods in various specific ways
<<abstract>>AbstractClass
templateMethod( )op1( )op2( )
ConcreteClass
op1( )op2( )
...op1();...op2();
ConcreteClass2
op1( )op2( )
...
Introduction to Design Patterns 24
Example: Observer Pattern
Defines a 1 to many dependency between objects so that when one changes state, all dependents are notified and updated.
Subject class maintains list list of Observer objects; has methods for adding and removing Observers and notifying them of changes of state in the Concrete Subject.
ConcreteSubject – particular class of interest Observer interface specifies the interface by which
ConcreteObservers are notified ConcreteObserver implements Observer interface and provides
particular behaviours for responding to changes in ConcreteSubject’s state.
<<interface>>
Observer
update(Event)
<<abstract>>Subject
add(Observer)remove(Observer)
notifyAll( )
ConcreteSubject
ConcreteObserver
update(Event)
*
For each observer oo.update( )….
Introduction to Design Patterns 25
Example: Strategy Pattern
Defines a family of algorithms, encapsulates each one, and makes them interchangeable: the functinality of an object can be varied by plugging in a different one.
Strategy interface specifies the interface implemented by all ConcreteStrategy classes (which implement various particular Strategies)
Context class maintains a reference to some ConcreteStrategy objectand invikes it through the Strategy interface to execute a strategy.
<<interface>>Strategy
ConcreteStrategy2
1Context
ConcreteStrategy2
<<interface>>LayoutManager
GridLayout
1Container
FlowLayout
…