The singleton patterns is a creational OOP design pattern that ensures that a singleton Class exists (usually just called a singleton), which can only contain one instance and has a public accessor method to that particular instance.
Usecase
- When multiple classes require access (associate with) to some global state, and there should only be one global state at all times and this state can change*.
- When some resources are used by multiple classes, and those resources need to be carefully monitored or strictly controlled.
*If you have a case where there is no state change, just use static methods!
Properties
- Singleton: The class that utilises the singleton pattern, which other classes need to access.
UML Class
classDiagram
class Singleton {
-Singleton self ~static~
-Singleton()
+Singleton getInstance()$
}
Singleton()
: The Constructor is private. ThegetInstance()
method constructs the object if it does not already exist. I.e. if we don’t have an instance of the Singleton,self
, then we create one.getInstance()
: The getter method is public and Static. It can be accessed everywhere, and does not require the Singleton instance to be created.self
: A Static, private instance of Singleton, which can only accessed bygetInstance()
.
Singleton Vs Static Methods
Pros vs Cons
Pros
- Ensures only one instance of a singleton exists always
- Allows global access from other classes
- Only one initialisation of the singleton instance, useful if construction is an expensive operation.
Cons
- Violates the Single Responsibility Principle, because it solves two problems at once: it allows global access to a class and ensures only one instance of the class exists.
- Really, really not a good idea for programs that use Multithreading, because multiple threads calling
getInstance()
could cause multiple instances to be generated. - Promotes strong coupling which is generally bad for unit tests and code in general. A change in the singleton class can break code everywhere.
Example
Imagine you have a text File
that needs to be edited in multiple ways. First, some more text needs to be appended onto it. Then, it needs to be formatted (aligned, fonts added, etc.). Lastly, let’s say a PlainText
file is created (for disabled people to access) by copying this file. A good coder would put each feature as a separate class:
- A
FileWriter
class that writes text toFile
objects - A
FileFormatter
and aFileCloner
class, which do what you expect.
We need to ensure a File
can only be accessed by one class at a time. We don’t want to begin creating the PlainText
file before we finish writing and formatting it. In other words:
- Our
File
object has multiple states: An open state (where it can be edited) and a closed state. - All our editing classes want access to this
File
object, and there should only be oneFile
object.
Sounds very similar to our Singleton Usecase.
Editing multiple files?
Yes, I know what you’re thinking. What if I wanted to edit multiple files? Well then, it doesn’t matter because if your program works like how a normal program does,
FileWriter
,FileFormatter
andFileCloner
still will be running on a single file. Instead, you could create aFileAllocater
class that chooses which singleFile
is the current working file.
#todo create UML for example.