 Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and with me is Phil Jepixi. Hey. How are you? Good. How are you? Doing good. Right. We are continuing our series on design patterns, and today we're going to look at factories. Yes. The whole set under that umbrella corp of the simple factory method, abstract factory. Cool. So, factories. I see these quite a bit, usually in code that other people have written with databases or services involved, so it's a fairly well-used pattern. Yeah. The goal really is, as we've said on several of these shows so far, to encapsulate or isolate the creation of an object from the code that needs it. Okay. New is glue. If I am creating an object and using an object at the same time, I am now stuck to the implementation. Okay. So, let me go back to the car metaphor that I used in the original show that kicked off this series. You drive, right? Yes, I do. Quite well, I would say. I'm sure you do. So, you have a car. Did you have to put the engine in it before you drove here to work today? No, I did not. It was already there. Yes. So, you had this dependency on the engine, but somebody injected that for you. Right. Right. Now, what happens if your car is in the shop? Can you drive another car? I can drive another car, yes. Okay. So, as long as it subscribes to the iCar interface, you can probably drive it, right? Right. Well, if you were only able to drive your own car and your car was in the shop, you couldn't come to work. Right? True. So, if you knew up that instance of your car directly when you need it and something happens to that instance of your car, you're stuck. Okay. So, what we want to do is we want to encapsulate or isolate the creation of these things, cars, from you. So, you just get up in the morning and say, I need a car. Maybe you're going to take your wife's car. Maybe you're going to take a rental. Maybe you'll take your car. It doesn't matter. It matches the iCar interface. Right? Right. So, that's the factory's... I see where this is going. What you're saying is, I could in my garage have a factory that builds cars for me. Yes. So, I can wake up in the morning and decide which type of car I want. As long as it subscribes to the iCar interface. Nice. Yeah. I'm digging this. I think tomorrow I'm going to new up a Ferrari. There you go. As long as you got the factory to make it. Okay. Back to reality. Back to reality. So, the simple factory, and I've got it crossed out, it's not truly a pattern. Again, that's really getting into academic semantics that I don't care about. But it is a code construct. And it really just simplifies object creation in one place. So, that's probably why they don't call it a pattern. But it really helps reduce duplicate code and enforce dry, which is don't repeat yourself. Okay. Right? I've said many times on your shows and in conference talks and certainly in the books and courses, if you write something once, you should encapsulate it. If you write the same thing twice, you need to back up and encapsulate it. If you write the same thing three times, I would ask you to stop being a programmer. Because any time you've got this duplicate code, you're risking some severe side effect bugs. Right. So, I've got a simple factory. Actually, let's look at the test. And again, like the other episodes, we're driving a lot of this discussion around unit tests so we can see how these things are used in action. Okay. This is not using a factory. This is just code that based on some sort of pizza type creates a new pizza. And you probably see this in lots of different places. Perfectly did, yeah. So let's say that I need to get a pizza in different places in code. So I clip or inherit this code into other methods. And any time I need a pizza, I call this little block of code. So what if I'm going to introduce a Italian? I guess I'll be an Italian style of pizza. Yeah. So I would do this, right? I would just say, case pizza type dot Italian. And I would, I don't have any implementation for that. Okay. And I'd have to do some refactoring to add as a pizza type and create a class that is a Italian pizza. But if I've got this code, and I'm pointing it to screen, which you guys can't see, if I have this code in multiple places in my application, I have to now remember everywhere I put that code to then add the Italian pizza option. Okay. If I don't do that, then in method B that maybe you're working with, you don't have the Italian pizza option. We've just introduced a bug. So at some point you'd say, oh, why don't I just create a method and I'll pass in the type of pizza I want to create and then it will know which pizza to create. Yes. We want to reduce that duplicate code and encapsulate the creation of the pizza. What we would rather see in our line of business code or our calling code is something as simple as this. Okay. Create pizza. Let me get the resolution change going on. So let me put a line break in. So I want to create a pizza of the New York style with some set of ingredients. And I just make sure that what I get back is actually of type New York. So that idea that, I mean eventually this list could grow long, but every time you want to create a pizza, you're going to have to add that whole case statement. You're pretty quickly hopefully going to decide, well, that's not very good. So you're going to move it somewhere else, create a class that does that for you. That's a factory. It is a simple factory. It's a simple factory. Right, but it's a factory. It is. Okay. And if we look at the simple factory, it really is just the case statement encapsulated in a static method. Got it. We had the discussion about static versus singleton with the singleton episode, which I'm not sure if we've already published or not, but if we haven't. Singleton, yes, we have. Okay. So we've already published it. Singleton. We're doing song in one, in two days. The singleton. Who is the first creation? So it was the previous episode. Yes, previous episode. So rewind, go back and watch that episode. But we had a big discussion about when is static okay versus when you need a singleton. Right. And a pizza factory is totally, well, any factory, simple factory, is a perfect example of when static is good enough. Okay. Because I'm not maintaining any state. Yep. I'm encapsulating the creation of a new object. Now, in reality, you probably wouldn't have these lines hard coded in there. You might be calling to a database. You might be calling to some other service to get the type back, but we want to encapsulate all that code in one place. Okay. So anytime we make changes, we make it in one place. Right. And we extract that newing up of an item away from the code that needs it. Okay. So that's the key, because when you say new is glue, then every time you knew something, there's gonna be a voice in your head saying, well, that's bad. Yes. New is glue. You eventually have to new it. You have to at some point, right? But keep in mind that this pizza, this simple factory is not actually using these pizzas. It's just creating these pizzas. Right. This is your garage. Yep. Creating a Ferrari. Yep. Because you've asked for a Ferrari today. Yep. But tomorrow you wanna go climb Mount Rainier. So you ask for a four by four and it produces a four by four. Okay. You don't care how it happens. It magically happens. Right. So the bad pattern, the anti-pattern, if you will, is to new something up and use it immediately. Yes. The pattern would be to let something else new it and then it just returns the instance. Right. And using factories is one way to accomplish that. Yep. Another way is dependency inversion, where you would use some sort of inversion of control container. We should probably do a show on that at some point where you've got something else creating it based on a configuration or a DI container, ASP.net core is a perfect example of dependency inversion in action. So regardless, you're, again, the pattern is take that newing out of the hands of the people that need the new thing. Okay. So. Cool. Very simple, not truly a pattern. We'll call it a code construct to keep all the academics happy. It's a good practice. It is a good. And it's, again, it's probably occurred to you to do that already. Right. Okay. And actually a good way to, let me back up into Visual Studio. This is Visual Studio toolbox after all. After all. And I can go into analyze and right here select analyze solution for code clones. And what this will give me, do you know if this is a enterprise on link feature or is this in pro? I don't know. I was just about to wonder was this, what is this a 2017 feature? This is a 2017 feature. Okay. And I just recently learned about it and I think it's absolutely awesome. So what it will find is places in your code where you have duplicate code. Oh, cool. So you run this analyzer and if you've got this switch statement in five, six, seven places, then it'll come back and say, hey, you've got duplicate code here. It's an exact match. It's a strong match. It's a weak match. And then you can go look and say, hey, I'm doing stuff up in here and here and here. Let's move that into a simple factory. Nice. All right. So we get into the first true pattern of the factory series and that's a factory method pattern. This uses a method to deal with the problem of creating objects, right? And I don't have to specify the exact class that will be created. The exact instance I should say, because we're coding to interface. So lots of words on the screen. It's really best explained just by going into the code. So let's look at the factory method tests and what we want here. And again, let me do a line break because of the resolution change. So service book is 3000 by 2000. We're not recording at that. So I gotta remember when I'm sitting in my hotel room that I can't always show everything at once. I want a New York style pizza. Yep. And I call the New York style pizza store and I order a pizza. And it's gonna give me back a New York pizza. Okay, seems simple enough. I can make a class, call it New York pizza store, say create pizza. But you remember when we talked about the template method where we wanted to have some sort of order to a sequence of events. Right. Going back to the e-commerce problem. I want to take the order, process the payment, pick the inventory, packet, ship it. Right. We also talked about pizzas in a private, in a prior episode where we said, well, you know what? We have to take the order, process the payment, we have to make the pizza, we have to cook the pizza, we have to cut it, box it, deliver it. Right. At order of execution, we want to stay the same. Yep. So instead of doing all that duplicate code, when we look at the New York pizza store, it really is just an instance of an abstract class called pizza store. Here's our factory method where we create a pizza of type New York pizza. Okay. And we look at the base pizza store class itself. Here is, and again, it's not a template method because that pattern has some differences to this, but conceptually it's the same. We've got this method in the abstract class. We want to have some things happen. So this is not part of the pattern, the factory method pattern. This is the factory method pattern. We are calling this abstract method called create pizza. Okay. That's gonna be handled by a derived object. Okay. What do these look like to you? The pattern we've already talked about, right? That's the simple command. That's the command pattern, right? So again, you see how all these things kind of work together. Okay. So you're telling the pizza to bank yourself. Mm-hmm. And if it's a New York style pizza, it knows how to do it. If it's Chicago, it knows how to do it, et cetera, et cetera. So would you call, I see that you're not using the word factory in the name of anything you're calling, which I see used quite a bit, that people will call a factory to create something. Yeah, so with the factory method, it really is more embedded than that. Okay. And as opposed to being a specific factory. Now, in my experience working with the factory method, I would probably never do this alone, but in conjunction with the abstract factory, which we'll talk about next. Okay. But what we're really trying to do here is push that responsibility of creating the pizza into something that knows how to create the pizza. Okay. So I'm creating a pizza store and I say bring me a pizza. The pizza store knows how to create its specific style of pizza, right? So we have a New York pizza, Chicago pizza, et cetera. And that is done with a method call from the base class. So the base class says, you're derived, you take care of creating the right object. Okay. And we'll go to town on it. Okay. We'll bake it, we'll cut it, we'll box it, we'll ship it, et cetera. Got it. There are some shortcomings to this and let's say... So again, just to reiterate, the factory method pattern says take the newing of something and instead of newing and using right away, right, delegated essentially to a specific object that's in charge of creating it. Yeah. Is that about right? So this is done by creating, right here in the definition, done by creating a factory method, right? Either specified in an interface or implemented by child classes. In the example that we've shown today, it's implemented in child classes. Okay. So let's say you are only ever gonna create a pizza. There's no New York, Chicago, California, there's just a pizza, right? Would you still wanna use a factory? No, I would probably... Method there. No, I'd probably just use dependency inversion to put that pizza in where I need it. Okay. Right, I could put that pizza right in the constructor of whatever it needed to do, but there's no choices. Okay. So really what we're trying to do with all of the factories and even the simple factory is take those choices and push that responsibility to somebody who understands those choices. All we want is to receive a package from Amazon, let's say. Okay. We order something, we want to show up in two days if we have pride. Right. We don't care how it's packed. We don't care how it's shipped. We care that what we get is in one piece and it's still edible. If it's perishable, it's not broken, et cetera, et cetera. Okay, so to get back to when we originally started talking about patterns, they are, and the idea was that you have a problem to solve and somebody has already solved it for you. Yes. So the problem that the factory method pattern, we're gonna talk about the abstract, the problem here is that you have multiple types of classes that you're gonna create. So how do you handle that? If you only ever create a class and instance of a class, that's not a problem that the factory method was designed to address. Is that the correct statement? That is the correct statement. Okay. And one could argue pragmatically that if you only ever had one type of pizza, you don't necessarily need to code to an interface. If you only ever were going to have one car and drive one car, so the car you got when you were 16 and got your license, you were gonna keep for the rest of your life, so you couldn't drive anymore, do you really need to program to the iCar interface? Right. But in reality, is that realistic? And we have to do a balancing next year, it depends. Maybe, maybe not, and for some places, yes, in other places, no. That's the architecture answer, of course, it depends. But what we really need to think about is not gold plating. In other words, don't write code because we think someday down the road they're gonna need this, but still write code that we can extend without modifying. Right. So if I code to an interface, even if it's an iPizza interface, and I'm only ever going to get one style of pizza, but I code it to an interface, it's not much more work, maybe a couple lines of code, but now I can change the behavior through extension without having to go back and modify that code. Okay. Makes sense. Which is the open close principle from solid, right? Open for extension, closed for modification. Right. Right. So the abstract factory, again, a lot of words, so you can always pause the video if you wanna read it, but I'm just gonna highlight it. It provides a way to encapsulate individual factories that have a common theme without specifying their concrete classes. So again, I don't get hung up on real academic definitions. I really wanna just show it in code. So let's look at how we would call this, and this solves one of the problems with the factory method. The problem with the factory method is I have a New York style pizza store. I can only ever serve New York style pizza. Let's say that one. New Yorkers would say, what's the problem with that? Yeah, what's the problem with that? Well, what if the Mets and the White Sox are in the World Series? All right, so being a baseball fan. Let's be realistic. Let's say the Cubs and the Yankees are no offense to White Sox or Mets fans. So Robert has just turned off half of our listeners. Sorry, that was him, not me. No, but the point is, let's say that there's a Chicago team and a New York team, and they're in the series, and the mayors make a bet, if they tend to do, that if New York wins, that Pizzeria Uno and all those pizza places will have to serve New York style pizza for a day. And the reverse is also true. Those New York restaurants will have to serve Chicago pizza for a day. Well, with the factory method pattern, I would have to create a new pizza store to get that new style of pizza. Right. Technically, I mean, there are ways that we can change the factory method to accommodate that, but as you said, this problem's been solved. Let's leverage, stand on the shoulders of giants and leverage what's been done before us and solve it using an abstract factory. Okay, so here I have a New York pizza store with abstract factory. Again, naming is hard, so I just named them as obvious as I can for teaching purposes. And I say, give me a New York pizza store, but I want a Chicago style pizza. And I'm still calling ordered pizza, right? It's still taking the responsibility to that factory method of creating the pizza for me. Right. But what we've changed is we've now abstracted away the type of pizza into a pizza factory. The pizza factory itself is just an abstract class, create pizza. This is a theme that we keep saying over and over again. And if we look at the New York pizza factory, now this is not a New York pizza store, this is a pizza factory. Right. So we derive from pizza factory, we're gonna create a pizza, and the New York pizza factory creates a New York style pizza. So whatever it needs to do to make that type of pizza, and it's off to the races. A very slight change to the pizza store is we now have a pizza factory that we pass in when we create, for example, a New York pizza store. And that factory then creates the pizza that further extracting it away from the store itself. So here we have the New York pizza store with the abstract factory, which drives from, of course, pizza store with abstract factory. And by default, it will serve New York pizza. But we can always create a new instance of it and say, you know what, this time I wanna serve Chicago style pizza or California or Italian or whatever we wanna add in. So we've completely further abstracted away the creation of that object. Okay. Does that make sense? Yep. And so I like using them together, although again, implementation details very, we're talking about patterns. Somebody who's watching is probably gonna look at this and say, we're not really doing the factory method anymore because the factory is doing to create pizza and not to derive to class. And that's true. But you know what? It is how you implement it. The pattern is there to be implemented to fit your particular need. I did it this way because since I have to have the pizza factory to know which type of pizza to create, I said I'm gonna eliminate another call to a derived class and another override. I saved code. I didn't repeat myself and I pushed it all down here. Yeah, and again, this is not an academic exercise. Right. Techniques for writing code. Absolutely. Yep. All right, we're actually done. We talked about all the patterns, but that timer can't be right, can it? Well, it goes to 10 minutes, so it's turned over twice. Okay. So we're in the back room, Studio B. There's not a big clock on the wall. We have a little kitchen timer in front of us that says three minutes and I just panicked thinking that we were only talking for three minutes. No, we've been talking for 23 minutes. All right, well that's excellent. That makes an episode. Three minutes will be a little short. That would be. Okay, so that's the factory. The family of factories will call it that way. The factories. Okay, cool. So those are the factories. Yes. There's a fair amount going on in there, but hopefully you guys think that we did a good job of simplifying it and letting you know when you would use them and why, which I think for a lot of these is maybe even the hardest part, right? There's the code, but then there's the why. What problem are these solvings so that I should think about using them? And one of the problems that people run into with any pattern is the favorite pattern is the one they just read, right? So you might see this episode and go, I'm gonna use the factory pattern and that's really backwards. You need to have all these different patterns in your toolbox. And then when you're confronted with a problem, how do I solve that? Yes, exactly. The factories are meant to solve the, how do I new up something without having all that specific knowledge in the class that's going to be using it. Right, cool. All right, hope you enjoyed that one and we'll see you next time on Visual Studio Toolbox when we will continue this discussion because we're not quite done yet. We're not quite done yet. More patterns coming up. Thanks for watching.