Abstract Factory Pattern – Design Patterns (ep 5)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right it's time to talk about the abstract factory pattern now if you've already watched my video on the factory method pattern it's going to be really easy to understand the abstract factory pattern so the abstract factory pattern is extremely similar to the factory method pattern actually in some sense an abstract Factory is a set of factory methods so an abstract factory makes use of multiple factory methods so in other words if you haven't already watched my video on the factory method pattern pause this video watch that video and then come back or of course make sure that you have a solid understanding of what the factory method pattern is before moving on now if you're not already familiar with this playlist what we're doing is that we're walking through all of the patterns in this book head first design patterns one by one by one by one so if you're not already subscribed be sure to subscribe to the channel so that you won't miss the upcoming videos on the upcoming patterns from this book furthermore I highly recommend this book if you're new to design patterns if you're just looking for like a reference book with just a UML diagram for the short explanation this is not the book but if you're new to design patterns I highly recommend you to get this book but now the abstract factory pattern so let's start this off with the definition of the abstract factory pattern from this book the abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes one more time the abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes so if you contrast this to the factory method pattern the single difference between these two is that the factory method pattern constructs a single object and the abstract Factory construct multiple objects now if that feels slightly discouraging because it has such a cool name the abstract Factory I totally relate it feels silly that we learned about the factory method pattern which is not super difficult and then we hear about something called an abstract Factory it sounds extremely cool and then it turns out to be extremely simple I hear you the important point however is that even though it's technically very simple if you think about it it's kind of like dependency injection the the senior actually technically doing is extremely simple but if you start to look for places where you can apply this pattern or where you could apply for example dependency injection you actually start to realize that it's massively powerful like if you internalize the concept and really understand it and make use of it in some strategic places then suddenly your system is a lot more flexible so do not despair even if it's technically very simple it's actually massively powerful let's get into the pattern so let's start off by drawing up the UML diagram for the factory method pattern right remember we're not drawing the abstract Factory now we're drawing the pattern for the factory method that we talked about in the previous video the reason I want to do this is I want to emphasize how we go from a factory method pattern to an abstract factory pattern some of the factory method we've got a factory interface or abstract class which has a number of concretions that are concrete factories and this Factory has a factory method that returns some kind of product so it returns a product and it has first they call it the factory method I guess to emphasize that it's a factory method pattern and that this is the factory method of the factory method pattern but in order to be slightly more semantic let's call it guess product and of course then the concrete factory also needs to implement this method which returns a product and is called get product like so but now what is this product what is this type product that we're talking about so of course we need to have a class as a product so this could be again abstract class or an interface but something which is called product so we have this product and the factory creates products or more specifically the factory is an interface of which there are multiple implementations and any such concrete factory that is a factory any such concrete factory will create products if you call the get product method where if we create a product if you call the get product method and product of course are too abstract in the sense that they're an interface or an abstract class and there can be numerous implementations over the product so we need to draw a concrete product by the way please always take my UML with a grain of salt I am really not a UML expert so you have to see that as informal notation last time I didn't draw the arrow that's in the head first book which states that the concrete factory creates the concrete product so of course the point here is that on the general plane just a super quick repetition on the general plane there are factories that create product and depending on which particular factory you instantiate depending on which particular concrete factory you instantiate it might create different concrete products with different kinds of logic and passing different kinds of parameters etc etc now let's talk about the abstract factory pattern what is the difference between this and the abstract factory pattern here's the simple change we need to make the difference is that any factory does not only have the get product method but let's say that this get product method it's called get product a and then we have another method which returns a product and it's called get product B of course these are silly general names within a complex C but of course named named defensively but this is really the difference we're saying that any factory does not only create a single product but has the capability of producing multiple products so whenever you have a concrete factory that concrete factory cannot simply just have an implementation for get product it means minimization forgets product a and it means an implementation will get product B so let's change this down here to product get product a and product get product B so any concrete factory definitely has two methods one which is called get product a and one which is called guess product B which means that any concrete factory can produce two products has two implementations let's get back to the definition let us think about why this is definition says that the abstract factory pattern provides an interface for creating families of related or dependent objects families of related or dependent objects in other words product of kind a and products of kind B without specifying buying their concrete classes so without specifying which implementation of this product in other words whether it's one concrete product or another concrete product or another concrete product in this case gets product a and get product B are both products so here a gives you products and B gives you products but which concrete product this a method happens to return or which concrete product this B method happens to return is not a responsibility for the factory but is a responsibility for any concrete factory so what's the benefit it is the key point is really to think about the statement families related object so think about it this way let's assume we have the class product and we have concrete product and let's say I'm just slowly redrawing this in order to move faster let's say that we have product as a sort of interface or superclass and then we have a number of implementations of this product XY m & iy right we have a bunch of different concrete products what if in our application only certain pairs of product make sense it completely depends on what application we're building right but assume that in our application it only makes sense to use X's and Y's together and M's and ends together and i's and Y's together if you would try to use an N and an X together that just wouldn't make any sense in our program the example that they use in headfirst build on the pizza example that they talked about in the factory method pattern but because we've diverged from the Pizza example in the previous video let me mention that a common argument for where the abstract factory pattern is useful is when you're building UIs when you are building UI controls that need to be platform independent we'll talk more about this one would look at a concrete example but let's say that you are building an application that you need to deploy on Mac OS and that that same application needs to be deployed to Windows and to Linux for example now when we're saying product here let's say that we're actually talking about some kind of UI control some kind of UI like a window or like a button or label or whatever and say that these are a bunch of different UI controls and the point here that when we when we collected the pairs previously the point is that these different pairs represent different platforms so maybe the X&Y represents UI controls for Mac OS and M and n represents UI controls for Windows and iny UI controls for Linux so as I said it before within a context of a particular application but in the context of some particular requirement it might not necessarily make sense to mix certain objects with certain objects so in other words if let's say that the X here is a dialog like an alert box as in like a toaster notification that some text and an OK button so let's say that the X here is that dialog for Mac OS and let's say that the Y here is si the actual OK button of that dialog so the X here is the alert and the Y here is the is a button now if we follow that same structure with these with these other pairs MMN and I and Y then M here would be an alert box and n here would be a button and I in Linux would be an alert and Y would be a button so the point is that you can't make or I mean maybe you can but perhaps it doesn't make sense to make a Mac OS alert window with a window style button so if you just had factory method pattern so you had factory method pattern that you used in order to create buttons and alert boxes and all of the other stuff that you need to have created you wouldn't necessarily have control of whether you accidentally make something that's suitable for Mac with something that's suitable for Windows or Linux but with abstract factory pattern you can have that control so let's remove this stuff in the middle so the reason why you can have that control is very simple it is because a factory creates two products so in our case it was maybe the alert and the button and then any concrete implementation of this factory of this abstract factory has to be able to create both alert and buttons and then any concrete factory can be either a Mac OS Factory or Windows factory or a Linux factory which means that whenever we call guest product a we know that if we then later call get product B we'll get a product B that is suitable in combination with product a not to say that it means that we should compose them somehow but simply saying that the type B product that you get will make sense within the context of the type a products and you've gotten that the A's that you get will make sense in relation to the beast that you get they are of the same family of related product so let this be a bit more specific here or let's expand this just to think about it so this means that we don't actually just have one concrete factory we actually have multiple concrete factories in order to save space I'm just going to draw it like this right so imagine that they're a bunch of factories behind each other here so what I mean here is that we have let's say concrete factory one and concrete factory two behind the concrete factory one and concrete factory three behind concrete factory - so let's even draw these arrows we have one two three so the point is that we have multiple concrete factories so there is the definition of a factory and a factory has to create product has to be able to create a product and have to be able to create B products and then because this is an abstract class or an interface we can have multiple implementations of this interface we can have multiple concrete factories now what they're doing in this book and what they're doing in most of the other guides that I've found is that they didn't really talk about abstract Factory in the sense that we have two methods that return the same product they immediately went for two methods that return different products so in other words let's say that we have product type a product a and product of type B so instead of these products that we had before we will have two sets of products so we will have we will have product A's and we will have product B's I mean just make these a bit shorter so that we can actually fit need to hear so previously we had a sort of an abstract or an interface or product and then we had concrete implementations of product but now we have two abstractions we have the abstraction for product AIDS and we have the abstraction for product B's and these because because they are abstractions can actually have concrete implementations so we can have a concrete product a and we can have let me make this a bit shorter as well running out of space and we can have a concrete product B that implements the interface or inherits from product B so we have an abstract factory that has two methods get product a and get product B so we have the method get product e that returns products of type product a and we have the method get product B which returns products of type product B and if we then form the same sort of overlay 3d notation that we used here we can make it extremely explicit that this concrete product a is just of course one example of one of the different concrete products that we could have so we could have multiple concrete product AIDS so we can have multiple concretions of the type product a so concrete product a one concrete product a two and concrete product a three so the same way we do it here we have multiple concretions of product a then of course the same thing applies for product B now I realize it didn't draw this low enough that's just quickly redraw this so there might be multiple concretions of product being so the abstract class or the interface product B might have multiple concretions multiple concrete products B's so we have concrete product B one concrete product B two and concrete product B three so to quickly recap we have the abstract factory that has two methods get product a and get product B get part of a returns instances of type of product a and get product B returns instances of type product B and because the factory is an interface or an after class we can have multiple concretions we can have concrete factory one concrete factor to compute factory three etc but the same thing goes for the products so with the products we can since we have the abstract class or the interface product a and answer classes or the interface product B we can have multiple concretions we can have multiple concrete product a and multiple concrete product B's and again remember the point here is that depending on the scenario some concrete product is might not be suitable to mix with concrete products B's so this here on the top for example might be the concrete product a suitable for Mac OS while this on the top here is the concrete product be suitable for Mac OS and then you wouldn't want to mix one product a which is suitable for Mac OS with another product B that is suitable for Windows for example let's use the same color coding in the concrete factory for the return types so you have product B in green and product a in red and what we've drawn now look much more like what's in the head first book and what's in most B sort of example if you find on the internet and elsewhere I just really think it makes sense to think about that the essence of the abstract factory pattern versus the factory method pattern is that the abstract factory pattern actually returns multiple products it returns multiple things whether these things happen to be of the same type or happen to be of different types is a totally different matter it's essentially the same thing that we're doing anyways it's essentially still the abstract factory pattern as far as I understand but please correct me in the comments if I'm incorrect because the point is that you can group different concretions within a specific concrete factory such that these this group of concretions to make sense together and that's the thing you can't do with the factory method pattern because you simply have a single factory method now let's finalize this diagram by drawing a few arrows from these concrete factories so this is where it gets a bit messy but we'll try and keep our head straight so a concrete Factory think about it the concrete Factory a has two methods and where one returns a product a and one returns a product B and it's going to have to return some of these one of the concretions of product a and one of the concretions of product B so this is the reason I layered them so let's say that the top factory here returns the top layer of these two and the factory behind that the second factory here returns the second layer of the product and the third factory here returns the third lair of these products let's try and draw these arrows so I got totally stuck thinking about how to draw this without making the arrows overlaps sorry I can't figure it out so hole just have to do with the path that we're on we'll continue on that but if you have a way of drawing this without making the arrows overlap please - absolutely free to share that in the comments I'm sure that would be massively helpful for me and as well as others if nothing else just extremely interesting but now moving on so let's draw this up so we have three concrete products beans we have three concrete product AIDS and we have three factories now the first concrete product B is created by the first concrete factory secondly the second product B is created by the second factory the third concrete product B is created by the third concrete factory and then exactly the same thing happens for the concrete product aid so the first concrete product a is created by the first concrete factory the second concrete product a is created by the second concrete factory and the third concrete product a is created by the third concrete factory so concrete factory one creates concrete product b1 and concrete products a1 concrete factory two creates concrete products b2 and concrete product a2 and concrete factory 3 creates concrete products b3 and concrete product a3 whoo point being that you have two types product a and product B you want to with the factory create both of them but not all concretions of product a makes sense in conjunction with all concretions of product B so you can't just let users of your code wildly create different instances instead you provide them with the number of concrete factories that create a family of these products together in other words it creates for example product p1 and product a1 and these two you know make sense together so with that concrete factory you can then give that concrete factory to user and that we will be able to create both both A's and B's and be sure that the A's makes sense in conjunction with the B's and vice-versa and that's really it I hope that make sense so the point is if you think about dependency injection if you think about providing someone with a factory think about that when we talk about the factory method pattern the point is that you are able to give some piece of code a particular Factory you're able to inject a particular factory into a particular location of your code so you have a method where you want to create a product but instead of using new to instantiate that product you pass a factory you pass an instance of a factory a concrete factory into that place and then you call you create or get product on that particular factory and then you get a product instance back we're doing exactly the same thing here but we're passing a concrete factory that can create multiple things so when we're coupling to the factory we're not coupling to a factory that only has a single factory method but we're coupling to an abstract Factory that has multiple that has multiple factory methods and that's really it it's the factory method pattern but with multiple factory methods now before we wrap up let me quickly mention an example of where this might actually be useful imagine that you are building some kind of app some kind of some kind of app and in this app you have a UI ineffably so let's say that we here have a we have a menu and we have some kind of list of items that's our UI for this screen and let's not even go to the to the point where we talk about platform independence let's just instead talk about the fact that you have a UI and you might want to have a dark theme at a light theme so it might be that you want to give users the ability to switch theme and if you think about it the dark theme probably has white text and the light theme probably has black text or something similar to that and this is really such a scenario this is really one of these scenarios where it doesn't make sense to mix all your components with all components because it doesn't make sense to mix white text with white background because then the user can't actually see so it kind of makes sense the thing that whenever you are creating UI controls you would create them through a single factory right through your system a single factory instance propagates and that single Factory is either a light theme Factory or a dark theme Factory and whenever you need a particular control in this application instead of instantiating that control you simply call the factory you ask the factory for that particular control so you ask the factory to create a button or create a list and that factory is responsible for not only giving you the control but making sure that with all of the controls that you can get within that factory make sense together so if it's the light factory whether you ask for a button or a list or a label they will all follow the same theme they will all be usable together and if you use from the dark theme the same applies they make sense together and now you have a very nice location - in the future extend your program to have multiple themes so you can have colored themes and it would be in some sense trivial to make sure that your theme makes sense across the board in order to make make sure that you're not mixing colors in an incoherent or nonsensical manner and that's it it's really not any more strange than that so now we've talked about multiple products but again I emphasize that I would think that it still the abstract Factory even if you had a single type of product but you had multiple concretions of that type of product and some of the completions don't make sense with other concretions and your factories and have multiple methods where they create multiple different or similar instances of this product so it doesn't necessarily in my mind have to be that the factory has one method that creates product of one type and another method that creates product of another type and another method that creates products of another type etc it could simply be that you have a factory that creates products of some type and then the next method also creates products of that type but of course it might be that when you call the first mess and you get a differently constructed instance from when you call the second method it's all about which concretion of the product you get and also what parameters you're actually passing to that concretion we shouldn't forget that it doesn't necessarily also have to be that you're creating multiple different conclusions it could simply be that you're creating the same concretion that you're passing in different parameters so so the essence of the abstract factory pattern versus the factory method pattern is that in the abstract factory pattern you want to have multiple products created you want to have multiple factory methods and this is why we're saying that the abstract factory makes use of factory methods because both of these methods get product a and get product B can be considered factory methods so let me quickly repeat the definition again before we wrap up the abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes in other words the factory only specifies that it creates things of type product a and the things of type product B but it doesn't specify what concrete product a it produces and what concrete product B it produces that is the job of any particular concrete factory so the abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes so that's it I hope that makes sense if not please ask any questions that you might have in the comments and please also make any suggestions or comments that you want to share in the comments because I'm sure your ideas will be not to be appreciated by others now if you're new to design patterns again I highly recommend you to get this book linked in the description beyond that be sure to subscribe so that you won't miss the next episode on the next pattern from this book thank you very much for watching and I'll see you on the next one
Info
Channel: Christopher Okhravi
Views: 208,964
Rating: 4.9366169 out of 5
Keywords: abstract factory pattern, abstract factory, design pattern, design patterns, head first, head first design patterns
Id: v-GiuMmsXj4
Channel Id: undefined
Length: 25min 54sec (1554 seconds)
Published: Sun May 28 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.