How to BREAK and FIX Singleton Design Pattern | Interview Question

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up everyone and welcome to daily code buffer in this video we are going to learn about the Singleton design pattern so let's get started now before we understand the single InDesign pattern in Java let's first understand what is Singleton object so here let me just show you within your application whatever the objects that you create we can create the objects in the different ways so within your application you need your objects to be created only one time at the time we will create the Singleton object so suppose if you take the example here okay this is the object and here you can see I am just telling that this is a DB connection object so whenever from my application whenever I want to do any DB operations what I will do is I will refer to this object that is already created and I will use that particular object to do all my queries so that's the idea about the Singleton object that you will create the object only once and the same object you will use across your application so you won't be allowing to create another object with the same specifications okay so here within this DB object what you will have is you you will have all the DB properties like URL password everything where it's going to connect how many connections and everything that you have and the same connection and the same object you will refer every time to create the queries or two to have the DB connections and everything okay now to create the object as a Singleton we have to follow few properties what Singleton object means that whenever you are creating the object from the class right we will be defining the classes right so this is a class so whenever we are defining the object of that class we should only be having only one object Okay so this is a DB connection class so whenever I take the object or whenever I want to use the object of this class I should only be having one class now how we will do the code in such a way that it will result in only one object so for that when we Define the class write the name of the class have a post it's an app how generally we create the object we create the object using the Constructor okay so whenever a Constructor is called it will create a new object so what we'll do is we won't allow objects to be created using the Constructor okay that's a simple thing so what we will do is we will give a private Constructor so if we give the private Constructor no one would be able to create the object of it okay that's the first thing now but we should be able to create the object once so for that reason what we have to do is we have to have one static instance of that particular class and with one static method we should be allowing to create the object so for this class whatever it is we can have a static field and with the static field we have a static method and with this static method it will return this object okay that's the only one thing so whenever we will call the static method from this class it will return the same object every time we won't be creating the new object that's it and whatever the properties we have right within this class whatever the properties that we Define in this class those also should be static and be directly instantiated okay that's it so once we Define all these properties that particular class will be always single cell and no new object will be created when we are working with that particular class so this was all about the theoretical part like what is Singleton class and what are the properties that we have to Define to create a Singleton class now let's see in action like how many different ways that we can create a Singleton class and how we can break it as well so let me go to the example here I have few examples noted down here you can see that I have few examples here now let's start with the basic example okay here you can see this is a very basic example where I have defined that this is a lazy Singleton class now you can see that this class I have created and for this particular class I have created a private Constructor so that means no one will be able to create the object of this class okay so one thing that we have followed from the principle the next thing is we should be having the static instance of this class itself so yes you can see that we've defined private static lazy Singleton as the instance equal to null so we have just defined the same class as the instance here and with that we have defined one static method that will instantiate the object and it will return the same object so here you can see we have defined that if instance equal to equal to null then create the instance of the lazy Singleton and return that particular object so if the object is already created then it will return the same object every time so now whenever I'm going to call Lazy Singleton dot get instance method it is going to return me the same object that is defined here okay so it will always result in the same object cool right this is how you will be creating the Singleton classes which will result in only one object when you are working with it but now when we are working with the multi-threaded application when we are working with multiple threads we need to take care about those multiple threads as well so in within this example only let's see like at this particular Point within this method if two threads are trying to use the same method same object that is the singleton.cat instance so both the threads will come here at this particular point and from that both the threads it will go to this particular line of code that is the instance equals to new lazy Singleton then for both of those threads the new object will be created and that new object will be assigned to it so you can see that with this Singleton class multi-threaded approach is not handled here right because both the two threads is getting the new object of the Singleton class that is violating the principle of the Singleton design pattern so how we can handle this the first thing that comes to our mind is to make this lazy initialization to the eager initialization so if we take this example of the eager's initialization what we are doing is when we are declaring the object at that time only we are instantiating that a particular object so when the class is loaded in the jvm itself at that time only the object will be created and jvm will ensure that whenever any thread is trying to access that object that object will be created first so from the get instance method you can see that we have directly returned the instance here we have not added any null check as well so within the jvm that clasp will be loaded and the object of that particular class will also be created at the initialization steps only and whenever any thread is trying to access it it will only get one instance so we solve the multi-threading problem here but the issue will be like if we are not using that particular object then also that particular object is created and stored in the memory so it will utilize the resources and those resources if not used will be wasted so what it will do is it will create the object though we are not using it okay if you are using it that's fine but if you are not using it in our application then also this object will be created it will be there in the jvm and it will be useless so you can see that it is solving one problem but creating another problem as well so how we can solve this problem where we can have the Singleton class as a thread safe as well and we are not using enough memory as well so for that let's go to the multi-threaded Singleton class like how we can have the multi-threaded Singleton okay the first thing that you can do is whatever the method get instance is that that method you can make it as a synchronized method once you make the synchronize method what will happen is only one thread at a time can access that particular method only one thread will be able to call that method at a time so at that time what will happen is if multiple threads are trying to call this method one method will be executing that particular method and the object will be created so till that time other two threads will be waiting for first thread to be completed and then only another thread will come and after that third thread will come so here you can see that there is a long waiting time for multiple threads so if you have hundreds of threads and all those threads will have to wait until all the threads complete their process so for that rather than using the synchronized methods what we can do is we can use the synchronized blocks So within the synchronized blocks what we will do is we will only add the synchronized block where we are actually creating the object because whenever we're creating the object that point only we have to make sure that we have a synchronized process because at the time only we want to make sure that only one thread is creating the object and the other thread is just using that object so rather than making the entire method as synchronized we will just make sure that couple of lines only is synchronized right so the things can be directly be utilized by the other threads so for that reason what we are doing is within the multi-threaded Singleton class we had one private Constructor that's the default thing that we have to do then we have the instance of the multi-thread Singleton class as well where we have defined as a null because we are not going with the eager initialization okay because eager initialization will waste the resources So within this multi-thread Singleton what we are doing is you can see we are first doing the null check okay that if the instance is null and at the time only we have to create the object and that particular portion only I have to make sure that that's the synchronous block okay if the object is already available then I can directly return the object that's a simple thing right so now if the object is not available synchronization starts from this point only but here is the point where we are doing the null check so Till There are multiple threads can come to this point and if the object is not created all those threads can see that the instance is null and they can still come to this particular point so till this particular point if object is null all those threads will come here and they will know that okay object is null so after that within the synchronized block we have done that if instance equals to null then create the instance okay so first thread will come here and it will check okay the instance is null so create the instance then second thread will come here and it will check okay if instance is null no we already created it right so at the time it will skip this and it will return this instance from here okay so you can see that we created a synchronized block and from that only one thread will go here and it will create the instance and rest of the threads will come here it will check for the instance is equal to null if not it will directly return the instance so from here we can understand that our Singleton class is threads up as well and it will not utilize is that much resources as well so it is going to be pretty efficient Singleton class now though you can see that we created a pretty efficient Singleton class but can you break the Singleton pattern that is the question every interviewer will ask you how to break the Singleton design pattern and how we can solve that problem as well let's understand that as well because that's really important thing to know about the Singleton design pattern as well so till here we understood how to create the single and design pattern in different ways now let's see how it will work okay so what I will do is I will go to my main class okay and here I have created one main method okay that's a simple main method and I have created the example example serialization so serialization is one of the ways that Singleton pattern will break okay what serialization will do is serialization Will convert your object into the byte form and that particular byte from data can be sent over the network or for the different files and anything and file retrieving back that byte format data will be again changed to the object okay so that's the similar thing that we are going to do here we are going to convert our object into the file and when we are retrieving we will retrieve from the file and convert to the object okay that's a simple thing that we are going to do so here you can see that in the example serialization method I have used the lazy Singleton class here okay and you can see with lazy Singleton class with lazy singleton.get instance I am getting the instance so I got the instance here okay and this is going to be the Singleton instance now what I'm doing is using the object output stream I'm converting this lazy Singleton and I'm writing to the output stream here so whatever the whatever the object was there I am storing that object in the object.obj and writing this class into that okay so my class would be saved in the object.object now with the object input stream I am reading this object.object so whatever the data is there in the object.object I am getting in the object input stream and with the read object I am converting back to the lazy Singleton okay so that's the normal thing that I'm doing here okay nothing fancy I'm storing into object.obj and reading from the object.obj file okay and I am closing the object now how we will get to know that two classes are same those will be based on the hash code values so here what we are going to do is we are going to check the hash code of the two objects that we have like the first object that we created and the this realized object that we have okay if both the objects have the same hash code that means both the objects are same and that's the Singleton class okay so let's run this and see what happens and here you can see that we got the object one and object two and both the values are different that is the object one hash code and object to Hash code both the values are different that means this both the objects are not same okay we should be having the same hash code to make sure that it's the same object okay so this is violating our principle of Singleton that only one object should be created so how to solve this this is a pretty big issue and this is very common as well like we do the serialization of objects in our application that's very normal process to do so to handle this what we have is we have one read resolve method so if we go to the serialized disable Singleton here okay here you can see that it is the same code as the lazy Singleton object but we have one method that we have overrided that is the read result okay now what read result method will do is read result method will be called when you are doing the deserialization of the object jvm itself will call this method we do not have to call it when the deserialization happens for the particular object this method will be called and whatever the process that we have to do we can do within this process so what we are doing is we call this method read resolve and what we did we returned the same instance available so rather than deserialization method getting the bytary and converting back to the object what we did is in the read drizzle method just use the same object itself you don't have to deserialize and do all the processes just use the same object so you can see that whatever the objects that we have defined we are just returning the same thing here okay so now whenever the desolization happens we should get the same object back okay so let's use this serializable Singleton and check our code so we will go back to main okay and what I will do is I will uncomment this and here you can see that it's the same thing that we have done right rather than the lazy Singleton class I am using the serializable Singleton and the same thing that I've done I have created the instance and I am storing in the object1. obj earlier I was storing in the object.obj and the same thing read I am doing I'm reading from the object input stream from the same object 1. obj file and I am printing the hash code values of both the objects okay that's a simple thing that I'm doing so now if you run this for this particular lazy Singleton we should get the different hash code but for this realizable Singleton we should get the equal hash code so let's run this and let's see what happens so here you can see that for the object one object 2 we got the different hash code but for this realizable Singleton we are getting the same hash code value you can see that three hashcode values are same so here you can see that serializable was one of the ways that can break the Singleton and we fix that as well with the serializable one the other way to break the Singleton design pattern is using the reflections we already know that using the reflections we can call all the different methods Constructors and everything within the class so let's see how we can break the Singleton design pattern using the reflection and what is the way to solve that as well so here you can see that within this example reflection okay let me just comment this and enable here so within this example you can see that we have one method that is the example reflection and what we are doing is within the lazy singleton.class we are getting all the declared Constructors okay and what we have is we have one Constructor declared within the lazy Singleton and that is also private okay as we have declared private no one would be able to create the object of the Singleton okay that's why we made it a private one so what it is doing is using the reflection it is trying to get all the constructors of the class okay we got all the constructors and it is taking the first Constructor because we only have one Constructor it is taking the Constructor and it is changing from private to public you can see it is changing the accessibility so if when we make it true it will change from private to public okay so now your Constructor is visible so with the constructor.getnew instance it will create a new object and that new object will be stored in this Singleton and within the lazy Singleton instance using lazy single tender cat instance which is going to give the new instance created so that is also going to be the new instance that is going to be created so you can see that we broke the Singleton design pattern using the reflection year we change the private Constructor to public and with that Constructor we created one object and we created one object using the get instance method that we have now if we run this we should be getting the value you can see that reflected hash code Singleton is different and the Singleton instance this is also different so both the hash code values are different now to solve this issue as well like breaking of the Singleton is in pattern using the reflection we can use the enums so if we go here let me just open the innum Singleton you can see that what we did we just created the enum Singleton and created the instance of it okay now this will solve all our problems because whenever we declare the enums by default those are static values so we can directly call them and whatever the constructors are called users are IV as a developers cannot call those Constructors jvm itself will call those Constructor and create the object of it and it will send us and as enums are thread safe as well we don't have to worry about the thread safety as well so when we are creating the Singleton objects using the enums that is going to be the threads of as well and it is not going to break using the reflections as well so here you can see that we did nothing we created the Singleton object we Define the instance as a inner and we have some methods so whenever we want to call any methods within the Singleton because that's what we do right so we can call using the enum Singleton dot instance dot do something okay so here you can see that I've defined the same thing here like whenever I want to use this we can call it this way so this will always result in the Singleton object and we will be able to call each and everything this way so it will always result in the Singleton design pattern so these are the different ways we can create the Singleton object and we also saw the different ways to break it and how to fix it as well so if you know this you will be able to answer this question in your interview very well so whenever you are going for the interview this is the question that you will be asked a lot and all these different permutations and combinations will be asked for your singletonian pattern like how many different ways you can create how you can break it how you can fix it and everything so we covered all those topics here so if you have any doubts regarding any of the things that we have covered then you can always ask me in the comment sections below if you like this video give us a thumbs up and subscribe to my channel for the upcoming videos you can also join my channel by clicking on the join button and support me I will see you in the next video till then Happy coding bye bye
Info
Channel: Daily Code Buffer
Views: 8,301
Rating: undefined out of 5
Keywords: coding, programming, data structures, algorithms, dynamic programming, design, patterns, singleton, singleton design pattern, design patterns, singleton pattern, programming language (software genre), java (programming language), object-oriented programming (programming language paradigm), software design pattern (field of study), learn to code, design pattern, singleton class in java, how to prevent singleton class from reflection, how to prevent singleton class from serialization
Id: ASI0TfcY_7U
Channel Id: undefined
Length: 19min 31sec (1171 seconds)
Published: Mon Oct 24 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.