10 Design Patterns1
10 Design Patterns1
Design Patterns 1:
Iterator, Adapter, Singleton, Flyweight
1
Design patterns
• design pattern:
A standard solution to a common software problem in a context.
describes a recurring software structure or idiom
is abstract from any particular programming language
identifies classes and their roles in the solution to a problem
2
Benefits of using patterns
• Patterns give a design common vocabulary for software design:
Allows engineers to abstract a problem and talk about that abstraction
in isolation from its implementation.
A culture; domain-specific patterns increase design speed.
3
Gang of Four (GoF) patterns
• Creational Patterns (abstracting the object-instantiation process)
Factory Method Abstract Factory Singleton
Builder Prototype
4
Describing a pattern
• Problem: In what situation should this pattern be used?
5
Pattern: Iterator
6
Iterator pattern
• Problem: To access all members of a collection, must perform a
specialized traversal for each data structure.
Introduces undesirable dependences.
Does not generalize to other collections.
• Solution:
Provide a standard iterator object supplied by all data structures.
The implementation performs traversals, does bookkeeping.
• The implementation has knowledge about the representation.
Results are communicated to clients via a standard interface.
• Disadvantages:
Iteration order is fixed by the implementation, not the client.
Missing various potentially useful operations (add, set, etc.).
7
Pattern: Adapter
8
Adapter pattern
• Problem: We have an object that contains the functionality we
need, but not in the way we want to use it.
Cumbersome / unpleasant to use. Prone to bugs.
• Example:
We are given an Iterator, but not the collection it came from.
We want to do a for-each loop over the elements,
but you can't do this with an Iterator, only an Iterable:
9
Adapter in action
• Solution: Create an adapter object that bridges the provided and
desired functionality.
public class IterableAdapter implements Iterable<String> {
private Iterator<String> iterator;
public IterableAdapter(Iterator<String> itr) {
this.iterator = itr;
}
public Iterator<String> iterator() {
return iterator;
}
}
...
public void printAll(Iterator<String> itr) {
IterableAdapter adapter = new IterableAdapter(itr);
for (String s : adapter) { ... } // works
}
10
Pattern: Singleton
11
Creational Patterns
• Constructors in Java are inflexible:
Can't return a subtype of the class they belong to.
Always returns a fresh new object; can never re-use one.
• Creational factories:
Factory method
Abstract Factory object
Prototype
Dependency injection
• Sharing:
Singleton
Interning
Flyweight
12
Restricting object creation
• Problem: Sometimes we really only ever need (or want) one
instance of a particular class.
Examples: keyboard reader, bank data collection, game, UI
We'd like to make it illegal to have more than one.
• Issues:
Creating lots of objects can take a lot of time.
Extra objects take up memory.
It is a pain to deal with different objects floating around if they are
essentially the same.
Multiple objects of a type intended to be unique can lead to bugs.
• What happens if we have more than one game UI, or account manager?
13
Singleton pattern
• singleton: An object that is the only object of its type.
(one of the most known / popular design patterns)
• Benefits:
Takes responsibility of managing that instance away from the
programmer (illegal to construct more instances).
Saves memory.
Avoids bugs arising from multiple instances.
14
Restricting objects
• One way to avoid creating objects: use static methods
Examples: Math, System
Is this a good alternative choice? Why or why not?
15
Implementing Singleton
• Make constructor(s) private so that they can not be called from
outside by clients.
16
Singleton sequence
diagram
17
Singleton example
• Class RandomGenerator generates random numbers.
private RandomGenerator() {}
...
}
18
Lazy initialization
• Can wait until client asks for the instance to create it:
private RandomGenerator() {}
...
}
19
Singleton Comparator
• Comparators make great singletons because they have no state:
a class that has only one instance for each unique state
21
Redundant objects
• Problem: Redundant objects can bog down the system.
Many objects have the same state.
example: Date objects that represent the same date of the year
• new Date(4, 18)
• new Date(4, 18)
22
Flyweight pattern
• flyweight: An assurance that no more than one instance of a class
will have identical state.
Achieved by caching identical instances of objects.
Similar to singleton, but one instance for each unique object state.
Useful when there are many instances, but many are equivalent.
Can be used in conjunction with Factory Method pattern to create a
very efficient object-builder.
23
Flyweight diagram
• Flyweighting shares objects and/or shares their internal state
saves memory
allows comparisons with == rather than equals (why?)
1- 100
(Street-
NumberSet)
"Univ. Way"
(String)
(Street- "Univ. Way"
Segment) (String) StreetSegment
StreetSegment
with
withinterning
interning 1- 100
(Street-
"O2139" NumberSet)
(String)
(Street-
StreetSegment
StreetSegment Segment)
101- 200
without
withoutinterning
interning 101- 200
(Street-
NumberSet)
(Street-
NumberSet) (Street-
Segment)
"O2139"
(String)
24
Implementing a Flyweight
• Flyweighting works best on immutable objects. (Why?)
25
Flyweight sequence
diagram
26
Implementing a Flyweight
public class Flyweighted {
private static Map<KeyType, Flyweighted> instances
= new HashMap<KeyType, Flyweighted>();
27
Class before flyweighting
public class Point {
private int x, y;
28
Class after flyweighting
public class Point {
private static Map<String, Point> instances =
new HashMap<String, Point>();
29
String flyweighting
• interning: Synonym for flyweighting; sharing identical instances.
Java String objects are automatically interned (flyweighted) by the
compiler whenever possible.
If you declare two string variables that point to the same literal.
If you concatenate two string literals to match another literal.
String a = "neat";
String b = "neat"; String n e a t
String c = "n" + "eat";
30
Limits of String flyweight
String a = "neat";
Scanner console = new Scanner(System.in);
String b = console.next(); // user types "neat"
if (a == b) { ... // false