You are on page 1of 41

Design Patterns

CSE 403, Spring 2007, Alverson

With material from Marty Stepp 403 lectures.


Design patterns
A design pattern is a time-tested solution to a
common software problem

y Patterns enable a common design vocabulary,


improving communication, easing documentation

y Patterns capture design expertise and allow that


expertise to be transferred

CSE 403, Spring 2007, Alverson


Online Readings
Easy reads:
y A survey of common design patterns, James Maioriello
http://www.developer.com/design/article.php/1502691
y What are design patterns and why do I need them,
http://www.developer.com/design/article.php/1474561

Deeper:
y Design Patterns:
http://c2.com/cgi/wiki?DesignPatterns
y C# examples
http://www.dofactory.com/Patterns/Patterns.aspx
y Java examples
http://www.patterndepot.com/put/8/JavaPatterns.htm
CSE 403, Spring 2007, Alverson
Popular patterns we’ll explore
y Creational
o Singleton
o Factory

y Structural
o Decorator
o Flyweight

y Behavioral
o Iterator
o Strategy

CSE 403, Spring 2007, Alverson


Pattern: Singleton
a class that has only one instance

CSE 403, Spring 2007, Alverson


Restricting object creation
y Problem: Sometimes we will really only ever
need one instance of a particular class.
o Examples: keyboard reader, printer spooler
o We'd like to make it illegal to have more than one

y Why we care:
o Creating lots of objects can take a lot of time
o Extra objects take up memory
o It is a maintenance headache to deal with different
objects floating around if they are the same

CSE 403, Spring 2007, Alverson


Singleton pattern
y singleton: an object that is the only object of its
type
o ensures that a class has at most one instance
o provides a global access point to that instance

o takes responsibility of managing that instance away


from the programmer (illegal to construct more
instances)

o provide accessor method that allows users to see the


(one and only) instance

o possibly the most known / popular design pattern!


(this should tell you something)
CSE 403, Spring 2007, Alverson
Implementing Singleton
y make constructor(s) private so that they can
not be called from outside

y declare a single static private instance of the


class

y write a public getInstance() or similar


method that allows access to the single instance
o possibly protect / synchronize this method to ensure
that it will work in a multi-threaded program

CSE 403, Spring 2007, Alverson


Singleton sequence diagram

CSE 403, Spring 2007, Alverson


Singleton example
y consider a singleton class RandomGenerator that
generates random numbers
public class RandomGenerator {
private static RandomGenerator gen = new RandomGenerator();

public static RandomGenerator getInstance() {


return gen;
}

private RandomGenerator() {}

...
}
y possible problem with this class?
Always creates the instance, even if the class
is not used.
CSE 403, Spring 2007, Alverson
Singleton example 2
y variation: don't create the instance until needed
// Generates random numbers
public class RandomGenerator {
private static RandomGenerator gen = null;
public static RandomGenerator getInstance() {
if (gen == null) {
gen = new RandomGenerator();
}
return gen;
}
...
}

y what could go wrong with this version?

CSE 403, Spring 2007, Alverson


Singleton example 3
y variation: solve concurrency issue by locking
// Generates random numbers
public class RandomGenerator {
private static RandomGenerator gen = null;
public static synchronized RandomGenerator
getInstance() {
if (gen == null) {
gen = new RandomGenerator();
}
return gen;
}
...
}

y Is anything wrong with this version?


CSE 403, Spring 2007, Alverson
Singleton example 4
y variation: solve concurrency issue without
unnecessary locking
// Generates random numbers.
public class RandomGenerator {
private static RandomGenerator gen = null;
public static RandomGenerator getInstance() {
if (gen == null) {
synchronized (RandomGenerator.class) {
// must test again -- can you see why?
// sometimes called test-and-test-and-set
if (gen == null) {
gen = new RandomGenerator();
}
}
}
return gen;
}
}

CSE 403, Spring 2007, Alverson


Singleton exercise
y Consider your projects. What classes could be
a singleton in this system?

CSE 403, Spring 2007, Alverson


Pattern: Factory
(a variation of Factory Method, Abstract
Factory)

a class or method used to


create objects easily

CSE 403, Spring 2007, Alverson


Problem: Bulky GUI code
y GUI code to construct many components quickly
becomes redundant (here, with menus):
homestarItem = new JMenuItem("Homestar Runner");
homestarItem.addActionListener(this);
viewMenu.add(homestarItem);
anotherItem = new JMenuItem(“AnotherItem");
anotherItem.addActionListener(this);
viewMenu.add(anotherItem);

y another example (with buttons):


button1 = new JButton();
button1.addActionListener(this);
button1.setBorderPainted(false);
button2 = new JButton();
button2.addActionListener(this);
button2.setBorderPainted(false);
CSE 403, Spring 2007, Alverson
Factory pattern
y factory: a class whose job is to easily create
and return instances of other classes

o instead of calling a constructor, use a static method in


a "factory" class to set up the object

o saves lines, complexity to quickly construct / initialize


objects

o allows you to defer instantiation until a later point

CSE 403, Spring 2007, Alverson


Factory implementation
When implementing a factory of your own:

y The factory itself should not be instantiated


o make constructor private

y The factory uses static methods to construct components

y The factory should offer as simple an interface to client code


as possible.
o Don't demand lots of arguments; possibly overload factory methods
to handle special cases that need more arguments.

y Factories are often designed for reuse on a later project or


for general use throughout your system
CSE 403, Spring 2007, Alverson
Factory sequence diagram

CSE 403, Spring 2007, Alverson


Factory example
public class ButtonFactory {
private ButtonFactory() {}

public static JButton createButton(


String text, ActionListener listener,
Container panel) {
JButton button = new JButton(text);
button.setMnemonic(text.charAt(0));
button.addActionListener(listener);
panel.add(button);
return button;
}
}

CSE 403, Spring 2007, Alverson


Pattern: Decorator
objects that wrap around other objects to add
useful features

CSE 403, Spring 2007, Alverson


Decorator pattern
y decorator: an object that modifies behavior of, or
adds features to, another object
o decorator must maintain the common interface of the
object it wraps up
o used so that we can add features to an existing
simple object without needing to disrupt the interface
that client code expects when using the simple object
o the object being "decorated" usually does not
explicitly know about the decorator

How is this different from inheritance?


• decoration is dynamic and allows flexibility
• decoration can be applied to many different objects
CSE 403, Spring 2007, Alverson
Decorator example: I/O
y normal InputStream class has only public int
read() method to read one letter at a time

y decorators such as BufferedReader or Scanner add


additional functionality to read the stream more easily

// InputStreamReader/BufferedReader decorate InputStream


InputStream in = new FileInputStream("hardcode.txt");
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);

// because of decorator streams, we can read an


// entire line from the file in one call
// (InputStream only provides public int read() )
String wholeLine = br.readLine();
CSE 403, Spring 2007, Alverson
Decorator example: GUI
y normal GUI components don't have scroll bars
y JScrollPane is a container with scroll bars to which you
can add any component to make it scrollable

// JScrollPane decorates GUI components


JTextArea area = new JTextArea(20, 30);
JScrollPane scrollPane = new JScrollPane(area);
contentPane.add(scrollPane);

CSE 403, Spring 2007, Alverson


Pattern: Flyweight
a class that has only one instance for each unique
state

CSE 403, Spring 2007, Alverson


Problem of redundant objects
y problem: redundant objects can bog down
system
o many objects have same state

o example: string/text structures used by document


editors
o example: File objects that represent the same file on
disk
‡ new File("mobydick.txt")
‡ new File("mobydick.txt")
‡ new File("mobydick.txt")
... How does this
‡ new File("notes.txt") differ from a
‡ new File("notes.txt") const?
CSE 403, Spring 2007, Alverson
Flyweight pattern
y flyweight: an assurance that no more than one
instance of a class will have identical state

o achieved by caching identical instances of objects to


reduce object construction
o similar to singleton, but has many instances, one for
each unique-state object

o useful for cases when there are many instances of a


type but many are the same

o examples in Java: String, Image / Toolkit, Formatter


CSE 403, Spring 2007, Alverson
Implementing a Flyweight
y flyweighting works best on immutable objects
o immutable: cannot be changed once constructed

class pseudo-code sketch:


public class Flyweighted {
o static collection (list) of instances
o private constructor
o static method to get an instance:
‡ if (we have created this kind of instance before),
get it from the collection and return it
‡ else,
create a new instance, store it in the collection and return it
}
CSE 403, Spring 2007, Alverson
Flyweight sequence diagram

CSE 403, Spring 2007, Alverson


Implementing a Flyweight
public class Flyweighted {
private static Map instances;

private Flyweighted() {}

public static synchronized Flyweighted


getInstance(Object key) {
if (!instances.contains(key)) {
Flyweighted fw = new Flyweighted(key);
instances.put(key, fw);
return fw;
} else {
return instances.get(key);
}
}
}
CSE 403, Spring 2007, Alverson
Class before flyweighting
y A class to be flyweighted
public class Point {
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
public String toString() {
return "(" + x + ", " + y + ")";
}
}

CSE 403, Spring 2007, Alverson


Class after flyweighting
y A class that has been flyweighted!
public class Point {
private static Map<String, Point> instances =
new HashMap<String, Point>();
public static Point getInstance(int x, int y) {
String key = x + ", " + y;
if (instances.containsKey(key)) { // reuse
return instances.get(key);
}
Point p = new Point(x, y);
instances.put(key, p);
return p;
}
}

CSE 403, Spring 2007, Alverson


Flyweight exercise
y Consider your projects. Is there an opportunity
to use a flyweight?

CSE 403, Spring 2007, Alverson


Pattern: Iterator
objects that traverse collections

CSE 403, Spring 2007, Alverson


Iterator pattern
y iterator: an object that provides a standard way
to examine all elements of any collection

y benefits:
o supports variations in the traversal of an aggregate
o simplifies the aggregate’s interface
o allows more than one traversal to be pending on an
aggregate
o removes need to know about internal structure of
collection or different methods to access data from
different collections – puts knowledge in the iterator

CSE 403, Spring 2007, Alverson


Iterators in Java
y all Java collections have a method iterator that
returns an iterator for the elements of the collection
y can be used to look through the elements of any
kind of collection (an alternative to for loop)

List<Account> list = new ArrayList<Account>();


// ... add some elements ...

for (Iterator<Account> itr = list.iterator(); itr.hasNext(); )


{
Account a = itr.next();
System.out.println(a);
}
CSE 403, Spring 2007, Alverson
Adding your own Iterators
y when implementing your own collections, it can
be convenient to use iterators.
class List {
public:
int size() {…}
boolean isEmpty() {…}
ListElement* get(int index) {…}
}
What do you need to
public class ListIterator { know to write next()?
int currentIndex;
public:
boolean hasNext() {…} Can there be
ListElement* first() {…} different
iteration
ListElement* next() {…}
ListElement* current() {…}
CSE 403, Spring 2007, Alverson strategies?
}
Pattern: Strategy
objects that hold alternate algorithms to solve
a problem

CSE 403, Spring 2007, Alverson


Strategy pattern
y strategy: an algorithm separated from the object
that uses it, and encapsulated as its own object
o each strategy implements one behavior, one
implementation of how to solve the same problem
o separates algorithm for behavior from object that
wants to act
o allows changing an object's behavior dynamically
without extending / changing the object itself

y examples:
o file saving/compression
o layout managers on GUI containers
o AI algorithms for computer game players

CSE 403, Spring 2007, Alverson


Strategy example: Card player
// Strategy hierarchy parent
// (an interface or abstract class)
public interface Strategy {
public Card getMove();
}

// setting a strategy
player1.setStrategy(new SmartStrategy());

// using a strategy
Card p1move = player1.move(); // uses strategy

All strategies must declare (the same) interface common to all


supported
CSE 403, Spring 2007,algorithms
Alverson
Selecting a design pattern
y Consider how design patterns solve design problems
o You’ll need to get familiar with them first

y Consider design patterns of similar purpose to select the


one that best fits your situation
o Creational
o Structural
o Behavioral

y Consider the aspects of your system most likely to


change, evolve, be reused

Think of an example of where you could apply a pattern to


your project.
CSE 403, Spring 2007, Alverson

You might also like