The Singleton Design Pattern - Part of the Gang of Four

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is the singleton design pattern how do you use it and why is it important these are all great questions and this video I'm gonna answer all of them and more we're gonna look take a look at one of the more popular patterns in a gang of four set now in case you don't watched my videos before my name is Tim quarry my goal is to make learning c-sharp easier my goal isn't to entertain you is to turn you into a world-class developer I do that by making sure that everything I teach focuses on preparing you for the real world if you have thoughts on what you'd like to see me cover in a future video let me know down in the comments and I'll be sure to add to my suggestion list ok let's go to visual studio and we're gonna create rest start with a really simple project so a new project where use a console application we'll start here just to see how to set a singleton on our own basically without anything else helping us do it we're gonna create our own class with a singleton so let's go to a console app and we'll hit next I recall this console UI is fine and we'll call this singleton demo we'll hit create and we're not gonna run code necessarily we're a little bit of code just to see how it works but this really is a focus on the singleton pattern so let's start by creating class this kind of a setup okay so we're create a class that is not a singleton that it's going to kind of illustrate why we need a singleton again more like well let's tickle you see something and it helps you understand why you use something so let's create a class right click on console UI and say add new class and the class recalled this let's call it table server teal servers okay when this class is gonna represent is let's say we own a restaurant and in this restaurant we have waiters and waitresses who wait on tables so a new customer or set of customers comes in they're gonna ask for a table and that we're going to sign a waiter or waitress to that table where I say okay that's your table to deal with the handle and that's going in a rotating fashion that way we don't exclude one waiter or waitress from the rotation and they don't get any tables and thus no income or no additional income so therefore we're gonna have this class and it's gonna handle making sure we give out the rotation properly listen you're really kind of you can do this better probably in c-sharp this is an illustration okay so bear with me if it's not the ideal solution for this it's an ideal solution I think to demonstrate the purpose of Singleton's so make it public and then in here let's create a list of string so a private list of string and this is going to be servers equals new list of string and then in our constructor so ctor that's a snippet we tab twice and it creates the constructor snippet or creates a constructor from a snippet so in here we're gonna say server's dot add let's start with Tim and then servers dot add su and then we'll do Mary and Bob okay good short names I like shortening it's easier typing so I have now these four people who are servers their wait staff for the table and what I'm gonna do let me have a method in here so okay public method oops not public method public string and let's say get next server what that's gonna do is return the next person in line which means we have to have some kind of counter or or way to identify which number we're on so privates int current current server equal to zero and that's gonna be the next server we give out let's call it let's call it next server instead of current server so this is the next server so it's the index this is the index we're gonna pull from this list so we're going to do here is return server at this position so where as they read well let's let's capture it first so string output equals next of servers at position next server okay but then you have to figure out how to increment that value so we're gonna say next server plus equals one for add one to it but then if next server is greater than or equal to servers dot count then next server equals zero that's where you loop back to the beginning so it creates this constant rotation so if we have 0 1 2 & 3 so we're when next server says 3 will capture that input as Bob but then we add one to its gonna say 4 well there is no I up position for but the total count is four so therefore if next server is greater than equals count and since it will equal count the rest set it back to zero so the next server would be Tim again so we loop back to the beginning okay and we'll return output we do it in this order instead of returning this because we want to make sure we change the number after we capture the name so that's why we're doing it that way so this is our little class it just tells you who's up next that's all it does so if we go back to program CS and let's get rid of this and I'm gonna say table servers servers equals new table servers let's do a for loop I'll say for I is less than 10 so 10 total servers right asked for so let's do console.writeline arrest say servers dot get next server all right it's gonna loop through and let's let's add a strip beginning the next server is like so I couldn't do a string interpolation here with that network as well and at the end we'll do a console read line just to make sure that we don't close out of our console all right so let's just run this and see what it does it should loop through and give us all of our servers okay Tim sumeria Bob Tim sumeria Bob Tim sue that's exactly how you want to work it's gonna rotate through our servers giving us the next person who's gonna serve a table ok so that's that's all well and good but let's refactor this a little bit RSA private static void let's say host 1 get next server like so and yes this isn't a perfect coat because I want to refactor this since I have two of these host one host - I wonder a factory is in a different way but let's just go with the fact that this is how we're going to set things up so host one's gonna get the next server so console dot write line and let's actually write out this same thing only we don't have that instance we actually want to create an instance so let's just say that host one has their own list so table servers let's say static table servers host one servers equals or host one list equals new table servers so this is if you have let's say you have two hosts that are stand up a platform or a podium and as people walk in the door they greet the people they figure out which server is gonna serve them they take them to the appropriate table and seat them but you don't want that podium e empty because they're more people probably online coming and so you have two hosts and the next host steps up gets the information that people wait through the host one to come back and then they take their group host to take their group to the tables while host one steps up that's that kind of rotation well each host will have their own scratch pad of who goes next so we're going to create two scratch pads one for host one and one for host two so host one get next server the next server is host one list dot get next server well where I create another class another method that is host to get next server because that host two is walked at the podium and they're gonna consult their list and get the next server so let's simulate that now for a sake of simplicity we're going to do is in my for each let's change it to five as we don't overwhelm things I'm going to say ho one getnext server and then host to get next server so we're doing both instead of four then assimilates a two of them one walked up got the the next family coming in a sign of a person the next person the next host walked up got the next feeling coming in a sign up person and then it repeats okay let's see what happens in this situation if we run this the next server is Tim the next server is Tim again then Sue and Sue then Mary and Mary then Bob and Tim and Tim that's not right we don't want that that's not how the rotation is supposed to work and you could say well you can then instead of having to list you create one list cool except for the fact that right now this is all inside of our program class but what if we had a list somewhere else how we make sure those lists are synchronized how do you make sure that we don't have Tim get two tables in a row because that's unfair well the way I do that is to use the singleton pattern so let's do this so we have a a record of this actually know what note we're going to switch it all over we're gonna switch over table servers so if you have to to get screenshot of this if you want this code the way it is right now take a screenshot right now because I'm gonna update it to be a singleton so it's gonna change how things work so let's start by changing our constructor to private you might say well Tim that's how you create a new instance of table servers yes it is and it's private which means only things inside this class can instantiate this class that's correct so how do you instantiate that class I'm glad you asked let's come up here to the very top now we're sa private static static very important read-only and we're a create you since of table servers that's the class we're in right now and we'll call this let's call it instance equals new because we can create a new instance of it because the fact that we're inside this very class now there's a static and read-only why are those important well read-only is important because that means you can't overwrite this variable with something else once it's a sign it can't be reassigned with a new value now static is important because if you remember with your object-oriented programming and how classes work typically think of classes as being instantiated meaning you have to say equals new class name in order to create an instance of that class we also have a static keyword and a static keyword basically says you can access this without having the class be instantiate but it's private so we can't yet no worries we're gonna get there down below our constructor let's create a new method make a public again static and we're a return instance of table servers and we'll call this get table servers okay so this method is static which means its public so you can call this method by uh saying the class name dot the method name well this is going to return instance which is that private read-only instance of our class instance so the only way to instantiate this class is right here that's the only way we're gonna do it we instantiate it right here you can only do it privately so only in this class so we create one instance but when do we create this instance well we create this instance as soon as we start using this meaning it's not created till we need it it's kind of it's a it's a lazy instantiation so it's kind of wait until it's needed but once it's needed we're going to create a new instance of this table service so this is that would be the instantiated version so not only we have access to the static things but also the non static things like this get next server so when you say get table servers you're going to get an instance of table server but which instance you're always gonna get the same instance back this first instance cake that gets created so therefore everyone gets the same instance which means everyone has access to the same data with the same values let's look at how this would work let's go over here we can't do equals new table servers what we can do instead is we can say table servers dots get table servers this gets an instance of table servers and it gets the same instance we do the same thing right here which we're not actually using this right now but now we can do is run this same code over again now we've created a singleton let's run this and now it says Tim Sumeria Bob Tim sue Mary Bob Tim sue like it should like we're expected to so what happened that was different well these two requested an instance from table servers and they got the same instance so we called this right here it says get the next server host one list is the same as host two list therefore get next server increments that that I value a counter value and then this one has that new updated counter value and so it gets the next one in line now again I could have instant I could have given the same instance to both of these without using a singleton however if I have a method somewhere else in my application that also asked or get table servers it now we'll get a new insane instance not a new instance so if I want to do it kind of singleton pattern without using the singleton pattern what I could do is create an instance and then make that instance a global variable and everything point to it the problem with that is that now Ariens pointed us very we have to remember where the variable is and you might accidentally create a second instance that's not terribly safe with this pattern where you can't call the constructor directly so you cannot instantiate it directly you have to go through this method with this method no matter who calls this class in this particular class in programmed ICS or a totally different class somewhere else no matter who calls it they're all gonna get the same instance of our class now at this point you probably have one of two reactions if this is a newer a newer pattern for you the first reaction you might have is this is awesome I'm going to use this all the time I would encourage you not to this is a limited use pattern but let's talk about the other response first and we'll get back to this response the other response is this is stupid I would never use this I'll just create this occur a global instance and point to it from everywhere and to that I would say don't do that either ok so there's a there's a there's a meeting in the middle you have to have in your code I don't use a singleton instance very often but when I need to this singleton design pattern is really helpful and the reason why I don't use it very often is because I don't want to have this kind of data globally because remember this is lazy loaded but as soon as you start using this this instance will get created once that instance is created it will not get destroyed for the life of your application that means as long as your application keeps running this instance will stay open that can be especially problematic if you're on a web server for example because typically you don't restart your web server that often which means that if you have one of these not a big deal but if you have a hundred of these or a thousand of these all of a sudden your memory is filling up with stuff that's just probably shouldn't be there okay so you gotta make sure you're very selective about when you use a singleton you don't want your memory just stuffed full of these instances especially ones that hold data that you don't necessarily need to have open all the time on the other end there are times when you need to share data across your entire application and it makes more sense to have a data in memory that does to load it continually so for instance maybe you have certain configuration data now if you've watched my c-sharp application from start to finish course which is on youtubes a playlist for that in that course there's a little bit of of data that I wanted to have accessible across the entire application for the life of the application because I didn't I thought it's more expensive to continually load that data up and that's more expensive than just storing it once in memory and just accessing it and so I chose to create something like a singleton pattern but it wasn't a singleton pattern I was trying to not to add too much confusion because design patterns can be a little confusing for instance this pattern that might take you a little bit to understand the private static read-only and the private constructor and the public static method to get an instance I get that might take a few minutes to wrap your head around so I limit what how I did that but that's the kind of thing that I once in a while need is a little bit of data that I'm gonna access over and over and maybe even change once in a while that I want to have access to pretty much everywhere in which case a singleton is a great option now this singleton instance is designed to store data there are some times when you create a singleton instance where it's not designed to store data and we're gonna look at that in just a minute and usually that has to do with working with dependency injection so let's let's create a new project here just to see a singleton in action so let's right click on our solution and say add new project we're going right down to the more modern application Blaser web app and we're I call this a blazer server is fine and when I say a blazer server app no other changes here on the right and in here we're gonna see a different way to use a singleton so here's our blazer server project up here if we go to startup CS this is where we configure our services now this is dependency injection what's doing is it's saying when you ask for a certain thing here's what to give it okay so when you ask for in this case weather forecast service create a singleton of that weather forecast service so let's look at that weather forecast service the weather forecast service has a private static read-only string that has our summaries and then the get forecast async method so there is no storing of data in this class so why is it a singleton well we're gonna use it over and over again to call this method we don't want to as static because that that adds some other complexities we don't want in this case so instead we do is for a dependency injection system we have this has to be instantiated you have to say weather forecast service test equals new weather forecast service but in our configure services when we say give us an instance of the weather forecast service what we're saying is give us a singleton of that with a forecast service so when the first person asks for a weather forecast service they get a new instance when the second person asks for weather forecast service they get the same instance that that person one got so it it behaves the same way without having to write this code here okay so with our dependency injection system we can sometimes get around having to write all this extra code there's extra few lines at least but and here's the downside do you have to say singleton right here well no you could say add transient which means they'll create a new instance for every call you could also somewhere else in your code directly reference the services and say you know weather forecast service test equals new with our forecast service and that would work so while depends the injection does allow for and use the singleton pattern without having to add extra code to your class it's not quite the same as the actual singleton design pattern it returns a singleton meaning the same instance but it does not really adhere to the singleton design pattern okay I hope that makes sense there's a distinction there so if you think this is stupid there are places to use it there are places and times like this right here where it makes sense to make it a singleton if you this is awesome and you can't wait to use it everywhere remember you're storing all of this in memory now that's no big deal okay one class instance with four names in it is not a huge deal but remember this probably isn't how you're gonna get these names you pry little from a database and maybe they won't be servers maybe it will be orders well that might not be just four or ten or fifteen that might be a hundred or a thousand or ten thousand who knows so in that case you've got a lot of memory being used just holding onto this information you might be better off using a different mechanism to get the data maybe for instance you store what the last person was last server was and what their ID was and then you do a database lookup every time for the next person in line where you're kind of offloading that storage of of people's names to the database and you're just saying I'm okay with making a database call every time that might be lower as for in terms of your performance hit so this is a balancing act to make sure that you don't just say I'm going to use this all the time or I'm never going to use this use this as one more option in your toolbox to lower the performance hit of a certain action or mitigate a performance hit by allowing us to stay in memory long term just make sure that the cure isn't worse than the disease okay so that's the singleton pattern I've encourage you to try it out practice maybe if you have a little test app add a singleton pattern somewhere and just see how it works and either way Korea a new project try it out and may follow on do exactly what I did or something similar and just see what your results are play around with it okay thanks for watching if you have any questions or comments leave them down below in the comments I'll be sure to read them and respond appropriately ok thanks as always I am Tim quarry [Music] you
Info
Channel: IAmTimCorey
Views: 36,816
Rating: 4.9402986 out of 5
Keywords: .net, C#, Visual Studio, code, programming, tutorial, training, how to, tim corey, C# training, C# tutorial, asp.net, .net core, iamtimcorey, singleton design pattern, singleton design pattern in c#, design patterns, gang of four, singleton pattern, design pattern, object oriented programming, singleton, c# singleton, c# singleton pattern, c# singleton vs static, c# singleton example, c# singleton class, dependency injection, dependency injection c#, blazor
Id: ggqjVuJ0g_8
Channel Id: undefined
Length: 28min 40sec (1720 seconds)
Published: Mon Jul 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.