object Logger:
def info(message: String): Unit = println(s"INFO: $message")
Ensure a class only has one instance, and provide a global point of access to it
Encapsulate lazy instantiation[1]
It is important for some classes to have exactly one instance:
a printer spooler
a file system
an window manager
a data converter
How do we ensure that a class has only one instance and that the instance is easily accessible?
A global variable makes an object accessible, but it doesn’t keep you from instantiating multiple objects.
A better solution is to make the class itself responsible for keeping track of its sole instance.
there must be exactly one instance of a class, and it must be accessible to clients from a well-known access point
when the sole instance should b extensible by subclass and clients should be able to use an extended instance without modifying their code
Controlled access to sole instance.
Reduced name space.
Permits refinement of operations and representation.
Permits a variable number of instances.
More flexible than class-level operations.
Violates Single Responsibility Principle
May mask bad design (components know too much about each other)
In multithreaded contexts, a singleton may be created several times
Decreases the controllability of the client classes, which becomes harder to test
Lazy initialization can be used to ensure that the class is only instantiated when needed
Some languages already support singletons: Scala, Groovy, Ruby…
object Logger:
def info(message: String): Unit = println(s"INFO: $message")
// Use @Singleton to create a valid singleton class.
// We can also use @Singleton(lazy=true) for a lazy loading
// singleton class.
@Singleton
class Util {
int count(text) {
text.size()
}
}
assert 6 == Util.instance.count("mrhaki")
require 'singleton'
class Config
include Singleton
def foo
puts 'foo'
end
end
config = Config.instance
config.foo
Design Patterns: Elements of Reusable Object-Oriented Software. Erich Gamma, Richard Helm,Ralph Johnson, and John Vlissides. Addison Wesley. October 1994.
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return Holder.instance;
}
private static class Holder {
public static final Singleton instance = new Singleton();
}
}