Transcript Document

Scenario: Audio Clip
Imagine that your application played
an audio clip
 Based on user action, a different
audio clip may begin playing
 You want only one audio clip to play
at a time

1
Goal:
You want to control all references to
the AudioClip, and reference at one
time only one AudioClip – In sum,
you’ll want to manage the AudioClip.
(I borrowed this example from Patterns in Java)
2
How would you design this?
Not implement the functionality, or
 Create a class with only static
methods, or
 Create a global variable to reference
the clip, or
 Create only one instance of the
object that plays the clip; reference
only that object to play/stop/etc.

3
Problems with Static Functions/Global Var
Data not protected from errant
behavior; can be changed by any
other part of application
 Decrease your chances of writing
modular code (refactor or enhance)
 Objects no longer hold state and
behavior

4
Creational Patterns
Singleton
Singleton Pattern
Definition: Job of the Singleton is to enforce the
existence of a maximum of one object of the same type at
any given time. It does this by providing a global point of
access to the object.
Singleton belongs to the family of Creational design patterns, those
patterns that govern the instantiation process.
5
GofF UML Diagram
This Singleton class
controls access to the
object, with the static
Instance returning a
reference to the unique
Instance of the class
This is the unique
instance of the Class that
shouldn’t have multiple
instantiations
6
Scenario: MessageLogManager
Imagine that you want all messages, warnings, etc., displayed
to the user to also be written to a log file. You don’t want
to create multiple LogWriters, nor do you want to get into
the trouble of trying to write to the log file two different
messages at the same time.
7
LogManager UML Diagram
This class manages the
writing to the log. Note
that the constructor is
private.
The method getInstance is static
and public. You call the
getInstance() method that returns
one MessageLogManager .
8
Implementations

C++ is implemented with examples in
the Design Patterns Book (Maze
Example)

Java example is the LogManager
singleton diagrammed above.
9
Java Implementation
public class MessageLogManager
{
private static MessageLogManager instance = new MessageLogManager();
//this could be a Message object; for simplicity, it is a string here
private String message = "log message";
/*Constructor; must be declared -- if it isn't, a public constructor
is automatically created!
*/
private MessageLogManager()
{
}
public static MessageLogManager getInstance()
{
return instance;
}
public void printMessage()
{
System.out.println(message);
}
10
}
Java Test
import MessageLogManager;
class TestSingleton
{
public static void main(String[] args)
{
MessageLogManager mlm = MessageLogManager.getInstance();
System.out.println(mlm);
mlm.printMessage();
System.out.println(mlm);
}
}
11
Ugly, but validating results
MessageLogManager@256a7c
log message
MessageLogManager@256a7c
12
Possible Pitfalls
1.
Depending on your implementation, your Singleton class – and all of its data – might
be freed or garbage collected. If you cannot ensure a live reference to your Singleton
class, you will need to force one.
2.
The beauty of the Singleton pattern is NOT because the class is defined as a static
object, but because the method or function is static, and the constructor is private.
GofF: “A client that tries to instantiate Singleton directly will get an error at
compile-time. This ensures that only one instance can ever get created.”
3.
Subclassing: Place the getInstance() method in your subclass, and not in the parent
class (parent class could be an interface?). Registry of Singletons (beyond the scope
of this presenter).
4.
Multiple threads will also need to be carefully examined so a. one instance is created,
and b. thread synchronization stays simple.
13