I welcome to a new section of this video course creation all patterns in this section.
We will start with Singleton design pattern having a unique instance of a type in the entire program
and then we'll move on to build a design pattern where we'll be reusing an algorithm to create many
implementations of an interface.
Then we will explore about factory method delegating the creation of different types of payments and
then we'll dive into Abstract Factory.
Or we could say a factory of factories.
Finally we will have a look at prototype design pattern.
Now we move on to the first video of the section that deals with Singleton design pattern.
In this video we will first have the description and objective and take an example of a unique counter.
Then we'll see what are the requirements and acceptance and criteria at the end.
We will learn the implementation of Singleton patterns.
Have you ever gone through interviews as a software engineer.
It's interesting that when candidates are asked about design patterns more than 80 percent will mention
Singleton design pattern.
Why is that.
Maybe it's because it is one of the most used design patterns out there or one of the easiest to grasp.
We will start our journey on creation or design patterns because of that latter reason.
The Singleton pattern is easy to remember as the name implies it will provide you with a single instance
of an object and guarantee that there are no duplicates at the first call to use the instance it is
created and then reused between all the parts of the application that need to use that particular behavior.
You'll use singleton pattern in many different situations.
For example when you want to use the same connection to a database to make every query when you open
a secure shell that is s s h connection to a server to do a few tasks and don't want to reopen the connection
for each task.
If you need to limit the access to some variable or space you use a singleton as the door to this variable.
If you need to limit the number of calls to some places you create a singleton instance to make the
calls in the accepted window.
The possibilities are endless and we have just mentioned some of them as a general guide.
We consider using the Singleton pattern when these rules apply.
We need a single shared value of some particular type and we need to restrict object creation of some
type to a single unit along the entire program.
Now let's take an example of a unique counter as an example of an object of which we must ensure that
there is only one instance we will write a counter that holds the number of times it has been called
during program execution.
It shouldn't matter how many instance we have of the counter.
All of them must count the same value and it must be consistent between the instances.
There are some requirements and acceptance criteria to write the described single counter they're listed
here when no counter has been created before a new one is created with the value 0.
If a counter has already been created returned this instance that holds the actual count.
If we call the method add one The Count must be incremented by 1.
We have a scenario with three tests to check in our unit tests.
Now let's jump into writing unit tests.
First goes implementation of this pattern is slightly different from what you'll find in pure object
oriented languages such as Java or C++ where you have static members in go.
There's nothing like static members but we have package scope to deliver a similar result to set up
our project.
We must create a new folder within our go path source directory.
The general rule as we mentioned in the first section is to create a sub folder with the VCR provider
such as GetUp the user name and the name of the project.
For example in my case I use get hub as my VCR s and my username is FE So I will create the path go
path slash source get hub dot com slash pay go design patterns relational slash Singleton the go design
patterns instance in the path is the project name the creation or sub folder will also be our library
name and Singleton the name of this particular package and sub folder.
So let's create the Singleton folder type the command make directory iPhone P followed by the path which
I just mentioned done.
Now let's see the the same go path next.
Create a new file inside the Singleton folder called Singleton dot go to also reflect the name of the
package and write the package declarations for the Singleton type let's write the command Nanos Singleton
dot go now at GM new Nano let's add the package declaration lets me align the code lines properly okay
first let's save this file using control Oh and now control X as we are following a TDD approach while
writing the code let's code the tests that use the functions we have just declared.
The tests are going to be defined by following the acceptance criteria that we have written earlier
by convention in test files we must create a file with the same name as the file to test suffixes with
the underscore test dot go both must reside in the same folder.
So let's create the test file nano Singleton underscore test dot go at these lines of code to this file
the first test check something obvious but no less important in complex applications.
We actually received something when we asked for an instance of the counter.
We have to think of it as a creation or pattern.
We delegate the creation of the object to an unknown package that could fail in the creation or retrieval
of the object.
We also store the current counter in the expected counter variable to make a comparison later.
Let's add the code for the current account logic.
Now we take advantage of the zero initialization feature of Go.
Remember that integer types in go cannot be nil.
And as we know that this is the first call to the counter and it is an integer type of variable.
And we also know it is 0 initialized.
So after the first call to the add one function the value of the count must be 1.
The test that checks the second condition provides that the expected connection variable is not different
to the return connection that we requested later.
If they were different the message Singleton instances must be different will cause the test to fail.
Let's add the code for counter to the last test is simply counting 1.
Again with the second instance the previous result was 1.
So now it must give us do the last thing we have to do to finish our test part is to execute the test
to make sure that they are failing before implementation.
If one of them doesn't fail it implies we have done something wrong and we have to reconsider that particular
test.
Let us save the file.
Now we must open the terminal and navigate to the path of the singleton package to execute right at
the terminal.
Go test iPhone V and click enter.
So here is the output also.
Now let's move on to the implementation.
Finally we have to implement the Singleton pattern.
As we mentioned earlier we'll usually write a static method in an instance to retrieve the Singleton
instance in languages such as Java or C++ in go.
We don't have the keyword static but we can achieve the same result by using the scope of the package.
First we create a struct that contains the object which we want to guarantee to be a singleton during
the execution of the program.
Let's open our file navigate to the go directory source then get hub dot com and open the Singleton
dot file from the directory where you have saved it.
Let's replace this code.
Let me align the code lines.
Now save the file you must pay close attention to this piece of code in languages such as Java or C++.
The variable instance would be initialized to know at the beginning of the program in go.
You can initialize a pointer to a struct as nil but you cannot initialize a structure to nil which is
the equivalent of no.
So the VAR instance asterisk Singleton line defines a pointer to a struct of type Singleton as nil and
the variable called instance.
We created a get instance method that checks if the instance has not been initialized already instance
equal to equal to nil and creates an instance in the space already allocated in the line instance equal
to new Singleton.
Remember when we use the keyword new we are creating a pointer to an instance of the type between the
parentheses the add one method will take the count of the variable instance raise it by 1 and return
the current value of the counter.
So before executing this code remember to change the package name in the Singleton underscore test dot
go to creation all since the package name in the Singleton dot go is also creation all.
Let's save this file and go back to the terminal.
Let's run now our unit test again and here's the output.
A few words about the Singleton design pattern we have seen a very simple example of the Singleton pattern
partially applied to some situation that is a simple counter.
Just keep in mind that the Singleton pattern will give you the power to have a unique instance of some
struct in your application and that no package can create any clone of this struct before in this video.
Let's have a few words about the Singleton pattern with Singleton.
You're also hiding the complexity of creating the object in case it requires some computation and the
pitfall of creating it every time you need an instance of it.
If all of them are similar all this code writing checking if the variable already exists and storage
are encapsulated in the Singleton and you won't need to repeat it everywhere.
If you use a global variable here we are learning the classic Singleton implementation for single threaded
context.
We will see a concurrent Singleton implementation when we reach the sections about concurrency.
In the last part of this video course because this implementation is not thread safe in this video we
have learned about the Singleton design pattern in the next video.
We will have a look at the builder design pattern.