Design Patterns With material from Marty Stepp 403 lectures.

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
y
Patterns enable a common design vocabulary,
improving communication, easing documentation
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
y
y
Creational
o Singleton
o Factory
Structural
o Decorator
o Flyweight
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
o
y
Examples: keyboard reader, printer spooler
We'd like to make it illegal to have more than one
Why we care:
o
o
o
Creating lots of objects can take a lot of time
Extra objects take up memory
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
o
ensures that a class has at most one instance
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
y
y
make constructor(s) private so that they can
not be called from outside
declare a single static private instance of the
class
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
y
y
The factory uses static methods to construct components
The factory should offer as simple an interface to client code
as possible.
o
y
make constructor private
Don't demand lots of arguments; possibly overload factory methods
to handle special cases that need more arguments.
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
o
o
decorator must maintain the common interface of the
object it wraps up
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
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
y
normal InputStream class has only public int
read() method to read one letter at a time
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
y
normal GUI components don't have scroll bars
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
example: File objects that represent the same file on
disk
o
‡
‡
‡
‡
‡
new File("mobydick.txt")
new File("mobydick.txt")
new File("mobydick.txt")
...
new File("notes.txt")
new File("notes.txt")
CSE 403, Spring 2007, Alverson
How does this
differ from a
const?
Flyweight pattern
y
flyweight: an assurance that no more than one
instance of a class will have identical state
o
o
achieved by caching identical instances of objects to
reduce object construction
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
o
o
static collection (list) of instances
private constructor
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
y
iterator: an object that provides a standard way
to examine all elements of any collection
benefits:
o
o
o
o
supports variations in the traversal of an aggregate
simplifies the aggregate’s interface
allows more than one traversal to be pending on an
aggregate
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
y
all Java collections have a method iterator that
returns an iterator for the elements of the collection
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
know to write next()?
public class ListIterator {
int currentIndex;
public:
boolean hasNext() {…}
ListElement* first() {…}
ListElement* next() {…}
ListElement* current() {…}
CSE 403, Spring 2007, Alverson
}
Can there be
different
iteration
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
o
o
y
each strategy implements one behavior, one
implementation of how to solve the same problem
separates algorithm for behavior from object that
wants to act
allows changing an object's behavior dynamically
without extending / changing the object itself
examples:
o
o
o
file saving/compression
layout managers on GUI containers
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
y
y
Consider how design patterns solve design problems
o You’ll need to get familiar with them first
Consider design patterns of similar purpose to select the
one that best fits your situation
o Creational
o Structural
o Behavioral
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