This post follows chapter four the Observer Pattern of the book called Head First Design Patterns.. I will write the code in C# using Visual Studio Community 2019 in a Windows Presentation Foundation project. The code in the book is Java, but the languages are so similar that I was able to write it in C# easily.
In OOP, there comes a point in time when you must instantiate a class and create an object that actually occupies space in computer memory. It’s inevitable. The question is when. This is what the factory pattern is trying to answer. Factory method pattern is saying that when you are about to instantiate some with new, let’s encapsulate that. The Factory becomes responsible for instantiation.
Use Cases
In the book Head First Design Patterns, the authors use the example of a restaurant the makes pizzas. In the video by Christopher Okhravi on YouTube he changes that example to animals. Let’s talk about animals. Imagine you are making a game or a simulation where you need to create animals. You’ve got dogs, cats, and ducks. In your code, at run time, you don’t really know what kind of animal you need to create. It depends. Perhaps it’s a game and you want to simply create the object randomly. You need to fill a park with animals randomly. We, therefore, create in our code a factory. We’ll call it RandomAnimalFactory. We can create another one and call it BalancedAnimalFactory. So we have two factories.
Given that we have two factories, we should probably have a common ancestry. We could have an interface called IAnimalFactory. Maybe we could have a class or an abstract class as the common ancestry. In the video, Christopher says that in order to instantiate an animal, you might first need some computation and business logic to determine what kinds of parameters you want to pass to the factory. These parameters determine what kind of animal you want to construct as well as some of the specific features of that animal (size, speed, initial position, direction and so on). Put that logic into the factory. Also, you can use polymorphism. If you have a factory that is an instance, you can swap instances of factories at run time.
In the video, Christopher introduces another use case for the factory method pattern. Suppose you were building a video game. You are in a ship in space and you travel around and you have to shoot asteroids to destroy them so that they don’t bump into you and destroy your ship. You need to create asteroids. Asteroids have a size, a direction, a speed, and an initial location. Also, your game has levels. You have a factory that produces asteroids. Suppose that we use a factory in level 1, another factory on level 2, and another factory on level 3. Suppose we change our design here. Suppose we use parameters that we pass to the factory that changes how it works so that it can become the different levels.