0:14
Singleton is a creational pattern which describes a way to create an object.
The singleton pattern is one of the simplest examples of a design pattern.
However, you will see that it is a powerful technique.
As its name suggests, the singleton design pattern is about something singular,
having only one.
But what is it referring to?
What do we only want one of?
The Singleton pattern refers to having only one object of a class.
Let's say that you're working on a mobile app where the user can play poker.
This game has a preferences class to define where all the settings for
the user are stored.
These preferences include visual elements, such as the color of the playing surface,
and the design on the backs of the cards.
Imagine if more than one instance of the preferences class existed.
When the user is setting their preferences,
which preferences object is saving those choices?
And when the game is being displayed, which preferences object is used to
determine the design and colors for the game?
As you can see, having another preferences object doesn't make much sense, and
could lead to conflicts or inconsistencies.
Another goal of the Singleton design pattern is that the single object is
globally accessible within the program.
1:18
Now that we've discussed the design goal of having only one instance of a class,
how is this actually implemented?
If you're working on a small project on your own, you may do this informally.
After instantiating a class, you make a mental note to yourself not
to create another instance, and the problem is solved, sort of.
If you forget and
create another instance, then you might cause headaches for yourself.
This is also definitely not a workable solution in larger projects, or
projects with multiple developers.
We would like to prevent errors arising from multiple objects of a Singleton class
being instantiated.
The solution is to build this one, and only one goal, into the class itself, so
that creating another instance of a Singleton class is not only frowned upon,
but impossible.
In this way, you codify your design intent within the software.
2:01
How do you do this?
If you have a class with a public constructor,
this constructor may instantiate an object of this class at any time.
There's nothing to prevent a different part of the software creating another
object of this class.
Instead, then, you give the class a private constructor, so
that the constructor cannot be called from outside the class.
This creates an apparent contradiction.
The constructor is private, so it cannot be called outside its class.
So, how do you create an object of this class without a public constructor?
There are two key components to get around this.
The first is to declare a class variable called, say, unique instance.
This class variable will refer to the one instance of your Singleton class.
You declare the variable as private, so
that it can only be modified within the class.
The next step is to create a public method in the class that will
create an instance of this class, but only if an instance does not exist already.
We can call this method getInstance.
This method will first check if the uniqueInstance variable is null.
If it is null, then it will instantiate the class and
set this variable to reference the object.
If the uniqueInstance class variable currently references an object,
in other words, if there is already an object of this class,
then the method will simply return that object.
Because the getInstance method is public, it can be called globally and
used to create one instance of the class.
In a sense, it replaces the normal constructor.
Our class now realizes the Singleton design pattern,
because there can only be one instance which is globally accessible.
3:26
By hiding the regular constructor and forcing other classes to, instead,
call the public getInstance method, we added basic gatekeeping,
to ensure that only one object of the class is ever created.
The very same method is used to globally reference the single object,
if it has already been created.
Now, we can use our Singleton class in a large project, and not worry about
multiple instances, confusing developers and creating conflicts.
Another advantage of this version of a Singleton class is that the object is
not created until it is truly needed.
This is called lazy creation.
Lazy creation can be helpful if the object is large.
It is not created until the getInstance method is called, which is more efficient.
Of course, there can be trade-offs to using the Singleton design pattern.
If there are multiple computing threads running, there could be issues caused by
the threads trying to access the shared single object.
To decide if Singleton, or any other design pattern, is the best design for
the job, it helps to have a good idea of how it works and
its potential consequences.
Design patterns are defined by their purpose or intent, and not the exact code.
So, you may see variations of how Singleton is realized, but
their goal is always the same,
to provide global access to a class that is restricted to one instance.
In general, this is achieve by having a private constructor
with a public method that instantiates the class, if it is not already instantiated.
4:41
There are many objects that we would like only one of.
The preferences of an app, the print queue of your printer, the software driver for
a device.
It could be confusing, or even disastrous, to have multiples in these cases.
The Singleton pattern restricts a class to one object by building this
intent into the code.
It can be a powerful technique on its own,
or in combination with other design patterns.
As you design, think of where you can use the Singleton pattern to ensure, for
yourself or
other developers on the same project, that a given class has only one object.