Design patterns: Singleton part 2

I have not been here for a long time, mainly due to the lack of time and the topic to be discussed, but in the end the article is ready, as you guessed from the title the entry is the continuation of the first part about singleton because I thought that the first part is too poor ๐Ÿ™‚

 

Admission

Hi everyone, after a long break in writing, there is a lot of material to describe and a lot has happened to me all this time ๐Ÿ™‚ This article will be a continuation of the singleton, that is part two can be said, the first link is hereย http://devman.pl/programtech/design-patterns-singleton/ I thought that the first part about singleton is too short and many issues related to the singleton is not explained, you have before you the second part of the singleton, which I think clearly explains the topic ๐Ÿ™‚

We will also use unit tests today to demonstrate how they work with the singleton, later there will be a whole section on unit testing.

There is much to discuss today, but we can do it ๐Ÿ’ช

We’re going with a topic:)

 

Discussion

I will also remind you a little about what a singleton is, in short, the goal of singleton is to limit the class instance to one and create global access to it.

A singleton class object is usually created (though not always because there are different ways) through the getInstance() method because the constructor is private, so you can not send parameters to the constructor.

Singleton can be used wherever we need to have only one object, it can represent eg monitor, mouse, land in some game because there is only one :), etc.

And an example of using singleton in practice is, for example, a login mechanism because the login panel is only one, the whole website, eg, the Internet website uses only one login class object :). An example of singleton usage can be eg the event tracking class, because two classes are not needed to track events.

 

Intent

  • Limiting the class instance to one object.
  • The possibility of global access to the singleton class.

 

Problem

You have a project where you can not duplicate an object, there must be only one, unique object and you need a global access to this object.

 

Structure

The singleton pattern scheme looks like this:

It is very easy as you can see, the client calls the static getInstance() method, which creates a singleton object for it.

As in the table above, it is described that the defined theInstance variable is global as well as the getInstance() method.

And we’re going to work ๐Ÿ™‚

There are many ways to implement the singleton, but one by one, we’ll first see the most common ways to implement a singleton. And the most common are two ways.

 

Eager Initialization

The often encountered way of singleton implementation is the so-called eager initialization, its purpose is to create a private constructor and provide a static object field, and this field is returned by the GetInstance() method.

 

Static factory method Singleton

There is also a way to implement a singleton without the GetInstance() method with the public access specifier of the INSTANCE variable.

However, the Eager initialization method is more practical and flexible because it allows you to create a singleton factory without creating specific class types.

These are the two most common ways of implementation in my opinion, but there are many more, let’s move on.

 

Lazy Initialization

Another way to create a singleton is the so-called lazy initialization, i.e. create a singleton class object when it is needed, so it does not take up the resources of the computer when it is not in use.

Result:

It is also in C # way to shorten the lazy initialization code in .NET are ready functions.

This code is the same as the first from the Lazy Initialization point, just simply a shorter entry ๐Ÿ™‚

 

Protection before multithreading

The problem may be when you will need to use singleton from many threads, because then the result from the Lazy initialization code can be like this:

But there is also a way to protect the singleton, because what for do we have the word lock in C #.ย ๐Ÿ™‚

Now the result will usually be ๐Ÿ™‚

 

Static Holder singleton

There is also another way of singleton implementation, singleton will be created only after calling the holder class.

This solution is good when we operate in a multi-threaded environment and allows us to create a singleton factory.

 

Enum singleton

There is another way to create a singleton from a different class. ๐Ÿ™‚ This is a more concise way, but it differs from the enum statement of java. The most interesting is that there is no enum statement used at all, it is a Java equivalent.

As you can see instead of enum statement, generic types are used here, because enum works differently in Java and differently in C #. In this example, we made a singleton from the Product class. The disadvantages are that there is no lazy loading and we have no guarantee that there will be one Product class object and this is due to the public constructor. As we use generic types here, the constructor must be public.

It’s a bit of it, it’s time for a joke.

An IT specialist says to the computer scientist: – That’s enough programming, enough programming, enough a computer for today. Time to read something. And he began to read the e-book.

Actually, something in this lame joke is ๐Ÿ™‚

 

Creating a singleton with reflection

Singleton can be broken even if we have a private constructor, thanks to reflection. Reflections form a class object during the lifetime of the so-called runtime program.

Consider this example:

In the Main function, we will create a singleton using the GetInstance() method and with reflection.

Let’s see the result:

As we can see, hashcodes are not the same, so these singleton objects are not the same. In this way, you can break a singleton. Fortunately, there is an easy way to protect the singleton from reflections. Just add the code to the constructor:

Now we will get the exception:

 

Protection against cloning

It would also be good to protect the singleton from cloning, because it is known, if we would clone the singleton class, then it would not be just one class. ๐Ÿ™‚ Here’s how to do it in .NET:

All you need to do is add and change the MemberwiseClone() method in case C # this is quite simple ๐Ÿ™‚

 

Protection against serialization

You can also break the singleton by serialization in this way as shown below:

First, we create a singleton object then create the path to the file to which we want to save this object. Then we open this file and deserialize the saved object from this file and we broke the singleton as seen in the result below the hashcodes are not the same.

Result:

And how to protect against singleton serialization? In the case of C # it’s quite simple ๐Ÿ™‚ We just do not add the word Serializable.

And in Java, just add the readResolve() method to avoid serialization, in the summary I will add a link to the article in which most of the examples very similar to those here, is in java those who write in java will be easier to transfer examples from this article to java.

 

And probably everyone feels like einstein ๐Ÿ™‚

But this is not the end, we are going further ๐Ÿ™‚

 

Singleton unit testing

According to some singleton is untestable, if you remember to clean it before each test and if someone implements the singleton interface, which serves as its type, there will be no problem in testing or mocking the singleton, we will see how to test the singleton class example.

Here are examples of tests.

And here is the singleton class.

At the moment I gave a random example of tests, just to illustrate how it looks with the singleton.

For now, on SomeClass and SomeLogic() method, we do not pay attention, I’ve specially complicated this class to show how mocking works, but it’s for a moment. First, let’s focus on the tests themselves.

In our case, before each test call, we create a singleton object, then if we want to clear the singleton class then we have to call the resetForTesting() method, now the private variable _instance will be empty.

Now let’s see what the mocking looks like, this is the mocking class.

As we can see, we do not mock the singleton class only its interface, which makes mocking easier, set the dummy of the SomeLogic() method so that it always returns the true condition, no matter what argument we pass to the SomeLogic() method.

And using Dependency Injection, we pass the dummy of the singleton object to the SomeClass class and call the SomeLogic() method in the SomeClass class.

The result of all tests, of course, everything is fine ๐Ÿ™‚

 

Open-closed singleton

Some say that the singleton breaks the open-closed principle, but when we change the specific type of singleton to the interface, this problem disappears. Example below ๐Ÿ™‚

 

Real-life example

Government

Now let’s make a practical example using the singleton, assume that we have to make a system that counts the number of votes for each presidential candidate and chooses the one with the largest number of votes. Below is a picture to illustrate the situation.

Let’s see how it looks in the code

Everything is carried out in the singleton Government class. I do not think I need to explain anything here, it is a simple example.

Result:

In addition, we will combine the singleton with the strategy model, let’s assume we want to get rid of these if statements in the Election() method, these statements look ugly๐Ÿ™‚ , we will try to limit the number of if statements.

Let’s start with the classes of presidents.

Singleton class and interface.

The class of the strategy to which we pass the created classes in the Election() method.

And finally the client.

The result will be the same as in the example with no strategy.

Of course, there is definitely a better solution in the Election() method, to choose presidents eg using a dictionary or assign id to the presidents to find the president with the biggest vote for id, but I did not want to complicate it anymore, I just wanted it to be easy to understand .

Naturally, in the comments I encourage you to post your own solution, for the creator of the best solution will send interesting books in pdf about marketing, sales or programming, you can chooseย ๐Ÿ™‚

If someone will write their solution in the commentary, please provide an email to know where I should send these books ๐Ÿ™‚

 

Relations with other design patterns

 

Summary

And that’s the end of the second part about singleton ๐Ÿ™‚

Link to github with the whole code from this article:ย  https://github.com/Slaw145/SingletonPart2

This content also you can find on medium:ย  https://medium.com/@sawomirkowalski/design-patterns-singleton-part-2-9c3a6fb8e675

For many singleton is considered an anti-pattern, in part it is, but mainly because it is often abused, just use it with common sense and will not give us a big project errors every few minutes ๐Ÿ™‚.

All examples are here in C # is also a nice article that shows some of these examples in java, for those who write only in java, I think it will be a big convenience, here it gives you a link: https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples

I think I’ll stop writing my blog for now, I’m tired ๐Ÿ˜‚๐Ÿ˜‚

Do not take it easy I’m kidding ๐Ÿ™‚, the next article I think will be more specific about dependency Injection, but we’ll see it again.

As a standard, I remind you aboutย the newsletter, which I send notifications about new entries and additional information about the IT world in general.๐Ÿ™‚

Andย NECESSERILYย join theย DevmanCommunityย community on fb, part of the community is in one placeย ๐Ÿ™‚

โ€“ site on fb:ย Devman.pl-Slawomir Kowalski

โ€“ group on fb:ย DevmanCommunity

Ask, comment underneath at the end of the post, share it, rate it, whatever you want๐Ÿ™‚.

Illustrations, pictures and diagrams are from: https://sourcemaking.com/design_patterns/singleton

 
If that post was useful for you share it with your friends :)

Post a comment

avatar
  Subscribe  
Notify about