35
1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

Embed Size (px)

Citation preview

Page 1: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

1

TCSS 360, Spring 2005Lecture Notes

Design Patterns:Singleton, Memento, Flyweight

Page 2: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

2

Outline

Singleton pattern

Serializable interface and persistent objects

Flyweight pattern

Page 3: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

3

Pattern: Singleton

a class that has only one instance

Page 4: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

4

Restricting object creation problem: sometimes we will really only ever

need one instance of a particular class examples: keyboard reader, bank data collection we'd like to make it illegal to have more than

one, just for safety's sake

why we care: 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

Page 5: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

5

Singleton pattern singleton: an object that is the only object of

its type ensures that a class has at most one instance provides a global access point to that instance

takes responsibility of managing that instance away from the programmer (illegal to construct more instances)

provide accessor method that allows users to see the (one and only) instance

possibly the most known / popular design pattern! (this should tell you something)

Page 6: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

6

Restricting objects, continued

One way to avoid creating objects:use static methods instead Math, System, JOptionPane is this a good alternative choice? Why or why

not? Problem: lacks flexibility

Example: static methods can't be passed as an argument to a method, nor returned

Problem: cannot be extended Example: static methods can't be subclassed

and overridden like a singleton's could be

Page 7: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

7

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 possibly protect / synchronize this method to

ensure that it will work in a multi-threaded program

Implementing Singleton

Page 8: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

8

Singleton sequence diagram

Page 9: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

9

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() {} public double nextNumber() { return Math.random(); }} possible problem: always creates the instance,

even if it isn't used

Singleton example

Page 10: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

10

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; }}

What could go wrong with this version?

Singleton example 2

Page 11: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

11

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; }}

Is anything wrong with this version?

Singleton example 3

Page 12: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

12

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? if (gen == null) gen = new RandomGenerator(); } } return gen; }}

Singleton example 4

Page 13: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

13

consider a class RandomGenerator that generates random numbers

public class RandomGenerator { private static RandomGenerator gen;

public static RandomGenerator getInstance() { return gen; } private RandomGenerator() {} public double nextNumber() { return Math.random(); }}

Singleton example

Page 14: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

14

Singleton exercise

Let's make our game model a singleton. What other classes can be singletons in this system?

Open issue: What happens if we want a saveable game, where the game state can be stored onto the disk? Will there be any issues with this that are

unique to a singleton class?

Page 15: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

15

Pattern: Memento

a memory snapshot of an object's state

Page 16: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

16

problem: sometimes we want to hold onto a version of an important object's state at a particular moment

memento: a saved "snapshot" of the state of an object or objects for possible later use; useful for: writing an Undo / Redo operation ensuring consistent state in a network persistency; save / load state between executions of

program

we'll examine Memento in the context of saving an object to disk using streams

Memento pattern

Page 17: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

17

I/O streams, briefly stream: an abstraction of a source or target of

data bytes "flow" to (output) and from (input)

streams can represent many data sources:

files on hard disk another computer on network web page input device

(keyboard, mouse, etc.)

Page 18: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

18

Stream hierarchy

java.io.InputStream

AudioInputStream

FileInputStream

ObjectInputStream

java.io.OutputStream

ByteArrayOutputStream

FileOutputStream

ObjectOutputStream

Page 19: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

19

Serialization serialization: reading /

writing objects and their exact state using I/O streams

allows objects themselves to be written to files, across network, to internet, etc.

lets you save your objects to disk and restore later

avoids converting object's state into arbitrary text format

Page 20: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

20

Classes used for serialization

in java.io package: ObjectOutputStream class represents a connection to

which an object can be written / sent (saved) public class ObjectOutputStream

public ObjectOutputStream(OutputStream out)public void writeObject(Object o) throws IOException

ObjectInputStream class represents a connection from which an object can be read / received (loaded) public class ObjectInputStream

public ObjectInputStream(InputStream in)public Object readObject() throws Exception

FileInputStream, FileOutputStream can be constructed from a file name String

Page 21: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

21

Serialization example recommendation: use a Memento class that has

save/load code

// write the object named someObject to file "file.dat"try { OutputStream os = new FileOutputStream("file.dat"); ObjectOutputStream oos = new ObjectOutputStream(os); oos.writeObject(someObject); os.close();} catch (IOException e) { ... }

// load the object named someObject from file "file.dat"try { InputStream is = new FileInputStream("file.dat"); ObjectInputStream ois = new ObjectInputStream(is); ArrayList someList = (ArrayList)ois.readObject(); is.close();} catch (Exception e) { ... }

Page 22: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

22

Memento sequence diagram

Page 23: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

23

must implement the (methodless) java.io.Serializable interface for your class to be compatible with object input/output streams

public class BankAccount implements Serializable

{

...

ensure that all instance variables inside your class are either serializable or declared transient transient fields won't be saved when object is

serialized

Making your classes serializable

Page 24: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

24

Let's make our (singleton) game model serializable

What can happen if a singleton is saved and loaded? Is it possible to have more than one instance

of the singleton's type in our system? Does this violate the Singleton pattern? Will

it break our code? If so, how can we fix it?

Back to singleton...

Page 25: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

25

Singleton example 5

variation: has strict checks to make sure that we have not saved a stale reference to the singleton object

// Generates random numbers.public class RandomGenerator { private static RandomGenerator gen = null; ...

public double nextNumber() { // put code like this in methods that use/modify it if (this != gen) throw new IllegalStateException("not singleton");

return Math.random(); }}

Page 26: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

26

Pattern: Flyweight

a class that has only one instance for each unique state

Page 27: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

27

Problem of redundant objects

problem: existence of redundant objects can bog down system many objects have same state intrinsic vs. extrinsic state

example: File objects that represent the same file on disk

new File("mobydick.txt") new File("mobydick.txt") new File("mobydick.txt")

... new File("notes.txt") new File("notes.txt")

Page 28: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

28

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 to reduce object construction similar to singleton, but has many instances,

one for each unique-state object useful for cases when there are many

instances of a type but many are the same can be used in conjunction with Factory

pattern to create a very efficient object-builder examples in Java: String, Image / Toolkit,

Formatter

Page 29: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

29

Flyweight and Strings Flyweighted strings

Java Strings are flyweighted by the compiler wherever possible

can be flyweighted at runtime with the intern method

public class StringTest { public static void main(String[] args) { String fly = "fly", weight = "weight"; String fly2 = "fly", weight2 = "weight";

System.out.println(fly == fly2); // true System.out.println(weight == weight2); // true

String distinctString = fly + weight; System.out.println(distinctString == "flyweight"); // false

String flyweight = (fly + weight).intern(); System.out.println(flyweight == "flyweight"); // true }}

Page 30: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

30

Implementing a Flyweight flyweighting works best on immutable objects

immutable: cannot be changed once constructed

class pseudo-code sketch: public class Flyweighted {

static map or table of instances private constructor static method to get an instance

if we have created this type of instance before, get it from map and return it

otherwise, make the new instance, store and return it

}

Page 31: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

31

Flyweight sequence diagram

Page 32: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

32

Implementing a Flyweightpublic class Flyweighted {

Map or table of instances

private Flyweighted() {}

public static synchronized Flyweighted getInstance(Object key) {

if (!myInstances.contains(key)) {

Flyweighted fw = new Flyweighted(key);

myInstances.put(key, fw);

return fw;

} else

return (Flyweighted)myInstances.get(key);

}

}

Page 33: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

33

Class before flyweighting 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 this.x; } public int getY() { return this.y; }

public String toString() { return "(" + this.x + ", " + this.y + ")"; }}

Page 34: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

34

Class after flyweighting A class that has been flyweighted!

public class Point { private static Map instances = new HashMap();

public static Point getInstance(int x, int y) { String key = x + ", " + y; if (instances.containsKey(key)) // re-use existing pt return (Point)instances.get(key);

Point p = new Point(x, y); instances.put(key, p); return p; }

private final int x, y; // immutable

private Point(int x, int y) { ...

Page 35: 1 TCSS 360, Spring 2005 Lecture Notes Design Patterns: Singleton, Memento, Flyweight

35

References The Java Tutorial: I/O

http://java.sun.com/docs/books/tutorial/essential/io/

Java API pages http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectInputStream.html http://java.sun.com/j2se/1.4.2/docs/api/java/io/

ObjectOutputStream.html http://java.sun.com/j2se/1.4.2/docs/api/java/awt/FileInputStream.html http://java.sun.com/j2se/1.4.2/docs/api/java/awt/FileOutputStream.html

Cunningham & Cunningham OO Consultancy, Inc. http://c2.com/cgi/wiki?SingletonPattern http://c2.com/cgi/wiki?MementoPattern http://c2.com/cgi/wiki?FlyweightPattern

Design Patterns Java Companion http://www.patterndepot.com/put/8/JavaPatterns.htm