Python Abstract Factory Pattern Explained | Object Creation Made Easy

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back to my Channel today we are going to look at how you can implement the abstract Factory pattern in Python the abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes the abstract Factory pattern is also known as a factory of factories if you haven't watched my other video on the factory pattern then I advise you to do so you can find a link in the description of this video it is now time to code the abstract Factory pattern so here in vs code I've again gone and opened up an empty folder called abstract Factory python so again go ahead and hold Ctrl shift and P and then select create environment then go ahead and select a virtual environment for your current workspace and I'm going to select vnf also select The Interpreter I'll go for the global one again now the best thing to do is to start with the abstractions in other words our abstract products and then our abstract Factory and then we can create the concretions thereafter so let's start with abstract product a which is our language interface so in our case our language abstract Base Class so let's create a new file and call it language dot pi let's import ABC and the abstract method from the ABC module so from ABC import ABC comma abstract method and then let's mark this as our abstract product a then we can say class language and then it needs to extend the abstract Base Class ABC and then as you can recall we only have a single method for abstract product a and that is a method to greet somebody in a certain language so let's define an abstract method with the abstract method annotation and we will simply call it greet and it won't take in any specific method arguments the grid method will return a string and since this is an abstract method it'll not have a method body so simply say pass that's all we have to do so let's go ahead and create our abstract product B create a new file and call it capital City we can do the same from ABC import ABC comma abstract method this is our abstract product B so let's mark it as such and then we can say class capital city extend ABC and this time we have two abstract methods that we need to Define one for getting the population and another for listing the top attractions for given Capital City both will be abstract methods so again use the abstract method annotation we can say get underscore population for the first one and this one will return an INT let's say pass because the concretions needs to implement these methods and then let's create another abstract method and call it list top attractions the list top attractions method will return a list and again say pass okay so now we have both our abstract product a with agreed method and our abstract product B with a get population and list top attractions method then let's create our third and final abstraction our abstract Factory which we'll call International Factory so let's create a new file and call it International Factory this too will be an abstract Base Class so again from ABC import ABC comma abstract method and as you can recall from the class diagram it'll have two methods one for creating language and another for creating the capital basically methods for creating each of our abstract products therefore we need to import our language class from the language file and we also need to import our Capital City class so from capital city import the capital city class and then let's mark the international Factory as our abstract Factory we can say class international Factory needs to extend ABC because this is an abstract base class and then we need to Define two abstract methods so again let's use the abstract method annotation and then our first method will be called create underscore language foreign it'll return our abstract product a which is our language Base Class and then let's define another abstract method this one will be called create capital it'll return our abstract product B which is our Capital City Base Class okay so now we have implemented all of our abstractions including the abstract Factory and both our abstract products next let's go ahead and create a concrete product A1 and concrete product A2 and that is the concrete classes for the language abstract Base Class so let's create our first concrete class and call it English so create a file called English dot pi and then let's import the language abstract base class from the language file and let's mark it as concrete product A1 then class its name is called English it extends language and therefore we need to implement the abstract method the grid method and we are simply going to return a greeting in English and we'll keep it simple we'll say that the way that you should greet somebody in English is hello now we can do simula for the Spanish class so let's go ahead and copy everything create a new file and call it Spanish dot pi [Music] I'm going to paste everything there and simply change the class name to Spanish mark it as concrete product A2 and then let's say to greet somebody in Spanish you say hola so now we have completed the implementation of both our concrete product A1 and concrete product A2 next is concrete product B1 and B2 so that is our Capital Cities so firstly we've got London as the capital of England so create a new file called London the London class will extend the capital city base class so let's import the capital city class from Capital City import capital city let's mark it as concrete product B1 and then the class name will be London extending capital city and therefore we need to implement two abstract methods including the get population method and the list top attractions method so let's start with the get population method at the time of the recording the population of London was 8.9 million so let's go ahead and return 8.9 million then let's also implement the list top attractions method and we can say that the top attractions in London are Tower Bridge Buckingham Palace and Big Ben Okay so we've completed the implementation of our London concrete product B1 class let's copy everything there and then let's go ahead and create a new file and call it Madrid dot Pi Madrid being the capital city of Spain I'm gonna paste everything there let's change London to Madrid as concrete product B2 also extending the capital city base class and the total population for Madrid at the time of this recording was 3.2 million and for Madrid we've got different top attractions the first one being Royal Palace the second one there Prado Museum and our third top attraction there is retiro Park so now we have completed the implementation of all of our concrete products next up we need to implement our concrete factories so let's start by implementing our England Factory our concrete Factory one so creates a new file and call it England underscore Factory importantly it'll extend the international Factory so let's import that [Music] it'll also return the concrete product A1 and concrete product B1 therefore let's import English our English class from the English file and then we also need to import London as our Capital City our concrete product B1 let's mark it as concrete Factory one and then class England Factory that extends International Factory and therefore we need to implement both of the abstract methods starting with the create language method and we'll say that if the create language method is invoked on the England Factory we will return English our concrete product A1 and we'll also implement the create Capital method and if the create Capital method is invoked on the England Factory will return London as the capital city our concrete product B1 so now we have completed our concrete Factory one let's create our concrete Factory two and it'll be called Spain Factory so create a Spain Factory file now we can go ahead and copy almost everything from the England Factory and change some of the Imports and some of the class names there so we won't import English but Spanish from the Spanish file [Music] and we won't import London but rather Madrid from the Madrid file and then we'll say this is concrete Factory two and it is called Spain Factory so when the create language method is invoked we'll return Spanish as our concrete product A2 and Madrid as the capital city as our concrete product B2 Okay so we've now completed the implementation of all of our conclusions including the concrete products and concrete factories so next up we'll go ahead and create our client logic and that'll be in a main file so go ahead and create a main file so in our client code we will invoke the create language and create Capital methods on the concrete Factory so let's go ahead and import them from England Factory import the England Factory class and from the Spain Factory import the Spain Factory class then we can mark this as our client code and let's define a main method then let's start by instantiating the England Factory so create a factory variable and say England Factory a new instance of England Factory now our England Factory can actually produce two types of products and that is a language product and a capital city product so firstly we want to get the language so say language equals Factory dot creates language and then we also want the factory to produce a capital city product so we can say Capital underscore City equals Factory dot create capital and then let's print out our results so I'm going to use a formatted print and we want to start off by printing out the language that we're talking about here so let's say language and then we can get The Language by saying language dot underscore underscore class dot underscore underscore name in other words if the England Factory returns English we can get the class name English and print that here next we want to greet somebody in the given language and we want to see what that looks like so again a formatted print and we'll say greet and then pass language dot greet [Music] next let's print the capital city so it will look similar to where we print the language so we'll say capital and then the capital city class that's returned by thefactory dot underscore underscore class dot underscore underscore name Okay so we've got the language the greeting and the capital we also want to print out the total population of the given capital city and therefore we'll say total population and then in curly brackets we'll say Capital City dot get population we also want to get the top attractions so we can say top attractions and then invoke the list top attractions method okay and then to make sure that this main method gets called on the startup of our python application we can say if underscore underscore name equals equals underscore underscore Main underscore underscore and that is the startup argument for any python application and then we'll invoke main Let's test our code we can do so by opening up our Terminals and then typing python3 and then running our main.pi file and as you can see there the language is English the English way of greeting somebody is hello the capital city of England is London the total population of London 8.9 million and the top attractions are Tower Bridge Buckingham Palace and Big Ben so to test the Spain Factory we can simply change the invocation of England Factory to Spain Factory and then let's run it again and as you can see there language Spanish the Spanish way of greeting somebody is hola capital city of Spain is Madrid total population 3.2 million and then the top attractions are Royal Palace Prado Museum and retirement Park now if you look at this code you might say you don't like this hard coding of the concrete Factory there and I absolutely agree fortunately there is another approach that they call the provider approach and you'll see just now that the definition where we say an abstract Factory is a factory of factories will make absolutely sense when you see the provider so let's go ahead and create a new file and call it International provider now the international provider will be a factory method it will in fact look just like the factory method that we created when we coded the factory pattern and therefore it also needs a factory key so before we Implement our International provider let's go ahead and create an enam class that we will call Country so go ahead and create a new file and call it country dot pi so let's start by importing enam so from enum import enum and then we can say class country that extends enum and then we can Define our enum values and we want one for England equals one and we want another for Spain and Spain will have a value of two okay so our country enum will now be our factory key so let's start by implementing our International provider so the international provider needs access to the enum our country enum so let's import that it also needs access to both our concrete factories so we need the England Factory import the England Factory class and we also need the Spain factories so go ahead and import the Spain Factory class we also need our abstract Factory that will actually be the return type of its Factory method so also import International Factory and we can mark this as our provider let's call it International provider it'll have a static method remember that factory methods are generally static methods and that's perfectly okay because it actually returns a new instance of a given concrete class so let's define a method that is called create that takes in our factory key which is our country enum so country of type country and it will return our abstract Factory which is international Factory and then we'll use a match case we'll match on the country value and we'll say that case the country is England will return a new instance of England Factory case it is Spain [Music] will return a new instance of Spain Factory and then if we don't have a case for a given country value let's raise a value error so case underscore and then we'll raise a value error and say something like country is not currently supported so that is all we have to do for our provider so if we go back to our client code we can now say let's create a country variable and we can set that to something like country dot England now we need to go ahead and add the import and I'm going to use this quick fix in vs code but you can also manually import it if you want then this time around we won't say Factory equal Spain Factory instead we'll say International provider again I'll import it with this quick fix and then invoke create and pass in our country in on value so another thing we can do is to print out our country and I'm simply going to print out the value of the country enum now you might say but whoa you're hard coding it again man what's going on here and that's a good observation but I've got good news for you normally this value will come from a user either through a terminal or a user interface or it might come via an HTTP request to a rest API or something like that so when we say that the client logic will not change we are referring to this logic and in that country value will normally be passed by a user but to stick to the Simplicity of the abstract method implementation and to make sure that you exactly know how to implement it I'm simply hard coding it there but you can go ahead and type it in from the terminal or create a little user interface for you if you want to take it a little further but without any further Ado Let's test our code I'm going to clear the terminal and then run Python 3 and execute our main file and as you can see there our country is England now you might say you don't like that country.england name there and let's go ahead and change that to country.name okay I'm gonna clear the terminal again let's run it and there it looks a little better so the country is England in England they speak English the English way of greeting somebody is hello the capital of England is London with a population of 8.9 million and again Tower Bridge back in a palace and big Ben as London's top attractions now we can simply change the country inam valley to Spain run it again and in this time you'll see the country of Spain the language Spanish in Spanish they agree to you like this hola the capital city of Spain is Madrid with a total population of 3.2 million and again Royal Palace Prado Museum and retiro park as the top attractions so as you can recall the abstract Factory design pattern provides an interface for creating families or related or dependent objects without specifying their concrete classes in other words the family of objects that are related for example includes English and London and Spanish and Madrid and then we do not depend on the concrete classes in other words here you'll see we are getting back the international Factory there we are getting back the language our abstract Base Class language and there we are getting the capital city back which is also an abstract Base Class and our abstract product B so in our client code we are actually depending on abstractions in other words this client code conforms to the dependency inversion principle that says that you should depend on abstractions and not concretions so you might ask what is the advantage to that and the advantage basically links to another principle that forms part of the solid principles the dependency inversion being the D in the solid abbreviation for the solid principles and then the open close principle being the O in the abbreviation in other words this code will never change right that value will normally come from a user from a user interface or terminal so that's why we can say that the client code will never change and it's therefore closed for modification but it's open for extension because you can have many more concrete factories that extends the international Factory and implements its Methods at the same time we could easily extend this International provider with more cases for different countries and we wouldn't have to change anything in our client code so that is why this code also conforms to the open close Principle as you can see it's quite simple to implement the abstract Factory pattern in Python if you enjoyed this video please go ahead and like it and subscribe to our Channel till next time
Info
Channel: campbelltech
Views: 1,997
Rating: undefined out of 5
Keywords: Python Abstract Factory, Abstract Factory Pattern, Python Design Patterns, Python Object Creation, Factory Method Python, Python OOP, Design Patterns Tutorial, Python Programming, Python Development, Software Design Patterns, Python Extensibility, Python Code Structure
Id: Uwci2zPgiLY
Channel Id: undefined
Length: 29min 9sec (1749 seconds)
Published: Thu Sep 14 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.