QUESTIONABLE object creation patterns in Python 🤔

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

And then we turn around and do shit like reactJS which is just a fancy singelton that holds all your state and doles out copies on demand.

👍︎︎ 1 👤︎︎ u/Fault_tolerant 📅︎︎ Apr 30 2021 🗫︎ replies
Captions
there's one design pattern that gets a lot of flack you guessed it the singleton and rightfully so i'm gonna tell you why you should never use it especially not in python there is a generalized version of it called the object pool and that is a different story let's dive in if you're new here and you want to become a better software developer gain a deeper understanding of programming in general start now by subscribing and hitting that bell like there's no tomorrow so you don't miss anything design patterns are generally grouped into three categories creational structural and behavioral starting at the end behavioral patterns focus on allowing you to choose between different algorithms or how particular parts of your application should communicate strategy and observer are two examples that i discussed in previous videos structural patterns explain how to assemble objects and classes into larger structures while keeping those structures flexible and efficient so those patterns deal more with how to organize different parts of your application think of the bridge pattern as an example and finally creational patterns deal with providing control over creating objects in various ways and that's what i'm going to talk about today there are several creational design patterns i won't cover all of them in this video but one of them is the singleton you don't need it in python but it's good to know that it exists so you can recognize it and then remove it from the code you're working on the idea of the singleton is that it allows you to have one single instance of a class you can use it to represent things for which you need only one like a graphics device manager a logger or an event manager here's a class diagram it relies on two mechanisms of object orientation the first is a static or class method that gives access to an instance of the class the second is the private access modifier that allows access to a method only from inside the class by making the constructor private only the static method inside the class can create an instance and so the class has full control over who creates an instance of it in theory in practice not all languages provide support to create a singleton in this way and some languages need a more complicated setup to make sure you're not inadvertently creating a new instance for example in c plus a class can have multiple constructors including a copy constructor and operator overloading may also create new instances so you need to block all those things and python doesn't have access modifiers so you can't make the initializer private you can still create a class that behaves like a singleton though with some trickery this is an example of how you could in principle create a singleton in python the mechanism i'm using here is a meta class you can see that the singleton class inherits from type which makes it a meta class an example i made here is the logger so logger in this case has a meta class singleton and that makes it a singleton let me explain how this works well the meta class has a list of instances that it maintains so the idea is that for every class that is a singleton you maintain the instance in this dictionary the mechanism i use here is that i added a call method to the singleton meta class and the result is that call method allows us to add parenthesis and call the instance in this case the instance is a metaclass so actually what this does is behave a bit like a constructor and we need to do it in this slightly contrived way because we need access to the class so we can store the class and this is what the code looks like if there is not yet an instance of that class inside the instances dictionary we create it and then we return it so this means that practically speaking there's only going to be one instance and the instance is stored here creating the instance looks also a bit contrived because we're calling it via the super construction here and that's needed because if we call it directly on class we're going to end up in an endless loop because class again does this so we need to make sure that doesn't happen and then in the end we return the instance that we're looking for so what happens is i can now create a logger like so and then lock something and this is actually going to use this mechanism here to create the actual instance and you see it works it behaves just like a regular instance i can create a second one like this and then also log something there let's run this see it works in exactly the same way except now the difference is that because we have this singleton behavior both of these variables logger and logger 2 actually refer to the same object let me show you i'm going to print out the logger object and i'm going to print out the logger 2 object and as you'll see they both refer to the object at the same address so it's the same object if logger wasn't a singleton meta class so let's remove this so don't need a parenthesis then you see we get two different objects so this is a mechanism to use metaclass to create singletons there are other ways to do it for example you could also use a decorator and create a singleton that way i put a link to an article with a few examples in description below singletons are considered an anti-pattern for several reasons the first is that singletons break object-oriented design principles because if you inherit from it this allows you to create multiple instances of that singleton by creating multiple subclasses which shouldn't be allowed another issue is that you don't have control over creation when you access the instance you never know whether it's an existing instance or a newly created one and that leads to another big issue testing code with singletons is really hard because you can't easily create a new fresh instance for each test you want to run and finally singletons don't work well in multi-threaded applications due to a race condition where if multiple threads access the not yet instantiated singleton at the same time you end up creating multiple instances in python you shouldn't use a singleton at all because python has modules which offer most of the same functionalities and none of the problems i just talked about in fact i can't recall the last time i thought the singleton was a good solution to design problem i had in any language the object pool is a pattern that's not in the gang of four book it's a kind of generalization of the singleton pattern here's a class diagram as opposed to the singleton which allows only for a single instance of a class the object pool manages a fixed number of instances that's not possible with python modules and it can be useful in a few cases in particular if creating objects is expensive in your application and you need those objects only for a short time the object pool could be helpful think of managing database connections or graphics objects containing lots of mesh data that are drawn over and over again let's look at a code example and then i'll tell you a few things you need to watch out for when using the object pool pattern to demonstrate the optic pool i'm using a simple reusable clasp that represents objects that we can reuse let me create one of these objects and show you how it works so the object actually does nothing it simply has a test method let's run this code the only thing the test method does is print out a message and it actually prints the id of the object so we know what object we're dealing with and you can see the result here the object pool is responsible for managing a pool of objects and the way you can do it is by maintaining two lists one list of objects that are in use and another list of objects that are free so let's create a class that does this work for us initially the free and in use list are both empty and now let's add objects to the free lists next what we can do is add an acquire and release method to manage when you can use those objects i'm adding a type hint here to show that acquire returns a reusable instance if the free list is empty we should raise an error if there is an object available then we're going to move that object to the in use list remove it from the free list and return that object first make sure we have a reference to that object so that's the first object in the free list we remove that object from the free list and add it to the in use list and finally we return the object releasing the object is similar but the other way around obviously and that needs the object as a parameter this is the basis of the reusable pool now instead of creating the object directly here let's create a pool and let's say we give the size of two so we have two reusable objects and then we can use the acquire method to get objects let's run this and see what happens here we have an object and we're using it let's get a second object second object also works fine and you see you have a different id so that's a different object now if we try to retrieve the third object we're going to get an error because obviously there are no more objects available in order to make another object available we have to release one of the objects we had before so we're releasing the second object we retrieved we're acquiring new object and then let's call the test method again you see we have again two objects that we're using let me demonstrate that this r3 object is actually the same object as the one that we just released so i'm calling here the test method on the two objects we have here oh this should be below that obviously and then here we call again the test method so you see that the second and the third time we do it it's actually the same object because we released it here we're acquiring again and calling test on it one thing you could do to make this a bit easier to use is to create a context manager that automatically acquires and releases objects for you let's create a context manager for this the context manager obviously needs a pool in the enter method we're going to acquire an instance of reusable and return that we're storing the object as a member in the contact manager so we can use it later on to release it again and that's what we're going to do in the exit method so we have our reusable pool and now what you can do is use with and then our context manager that gets the pool this returns the object so we should give it a name here and then we're calling the test method on that object the context manager makes sure that objects are acquired and released so i can do this multiple times and every time the object will come to be acquired and released again now this reusable pool class you could in principle turn that into a singleton so you have access to it everywhere but much better is if you don't want to use the classes to actually turn it into a module and then the module has the acquire and release functions and then you simply import those and use those there's a few limitations to the example i just showed you first you can still create reusable instances outside of the object pool also you could write code that uses an instance after you've released it there are ways in python to impose more control by using meta classes to for example block calling a method on an instance that's not been acquired from the pool similar to what i showed for the singleton object pools can be useful but you do need to be careful first you have to make sure when you release an object to the pool that it's also reset back to a fresh state ready to be used by someone else your object pool in the end is responsible for resetting the objects a second issue is that if you don't reset objects properly you may end up leaking information for example an authentication token that wasn't cleared may give undesirable access to data multi-threading is also an issue with object pools where multiple threads may end up using the same object at the same time if you haven't done so already join me on discord for more in-depth discussions previews of upcoming videos and more thanks for watching take care and see you soon singleton there we have two lists inside a repos by making the constructor method public public behavioral patterns focus on allowing you to choose between different algorithms or how different that or hybrid or how particular parts of your application should communicate [Music]
Info
Channel: ArjanCodes
Views: 22,101
Rating: 4.9202814 out of 5
Keywords: object creation patterns in python, design patterns, write better python code, design patterns in python, design pattern tutorial, design patterns in software engineering, design patterns tutorial, design patterns in python 3, object pool python, object creation python, singleton, singleton class, context manager python, design patterns in python course, Gang of four books, creational design patterns singleton, creational design patterns, creational design patterns gang of four
Id: Rm4JP7JfsKY
Channel Id: undefined
Length: 15min 10sec (910 seconds)
Published: Fri Apr 30 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.