- The Singleton pattern "Ensure[s] a class has only one instance, and provide[s] a global point of access to it."
- The Singleton class is responsible for keeping track of its sole instance as follows:
- it provides a static "uniqueInstance" property to store the instance
- it provides a static "instance()" method that returns the instance
- the instance() method also creates the unique instance on first invocation
- our Logger class from the Observer example is a Singleton
- relevant org.moock.logger.Logger source code:
// CONSTRUCTOR
org.moock.logger.Logger = function () {
this.setLevel("INFO");
}
// THE "uniqueInstance" STATIC PROPERTY
org.moock.logger.Logger.log = null;
// THE "instance()" STATIC METHOD
/**
* Returns a reference to the log instance.
* If no log instance exists yet, creates one.
*/
org.moock.logger.Logger.getLog = function () {
// If no log exists...
if (org.moock.logger.Logger.log == null) {
// ...create one.
org.moock.logger.Logger.log = new org.moock.logger.Logger();
}
// Return the log.
return org.moock.logger.Logger.log;
}
- In ActionScript, there's no way to prevent another class from invoking the Logger constructor directly.
- In languages that can specify explicit access privileges (e.g., C++, Java), constructor invocation should be limited to Logger and its subclasses (i.e., "protected" in C++, or "default" or "protected" in Java)
- Singleton is a good alternative to a global variable because:
- a global variable pollutes the global namespace (might conflict with other globals)
- a global variable can't prevent multiple instantiations
- What if multiple applications are running, and each wants its own log?
- Make Logger subclasses, one for each application
- override getLog(), storing the Logger instance in the subclass's own static "log" property.