Simple Factory, Factory Method and Abstract Factory Patterns
Continuing from my previous article about design patterns, we can now discuss a few types of design patterns known as factories and understand their types.
If you have read my previous blog about why we should use design patterns, you should already know how important they are. The design pattern I will be discussing is the simple factory and factory method patterns which belong to the creational design pattern category.
Simple Factory
This design pattern works by creating products from one "concrete" factory so that we don't have to use a new keyword whenever we want to create a certain object. The factory creates new products dynamically in the runtime without specifying what product to generate.
It solves a lot of problems by encapsulating product creation. We can dynamically create different products without knowing the concrete definitions. This reduces coupling in clients' code. The design for a simple factory is as follows:
Example of a Simple Factory
Let's see an example of how a simple factory works:
First, we create an abstract product. In my example below, let's call it IPlayer.
Concrete products inherit from the abstract product. In my case, Knight,Mage, GrandMage, Lancer inherits from IPlayer.
Next, we create a concrete factory PlayerFactory that creates different products according to the type provided. In my case, it creates the PlayerType.
We now create new products from PlayerFactory rather than using new keywords everywhere.
The example using the pattern described is shown below.
Factory Method
This design pattern works by creating products from a factory without defining what object type to create. The main difference between this pattern and a simple factory is that we create an abstract factory rather than a concrete implementation of the factory in this pattern.
The concrete factory will then override the creation process and creates a product with its own implementation. The client doesn't have to worry about the actual implementation of how products are created. The design for the Factory Method is as follows:
Example
Let's see an example of a factory method design implementation:
Create an abstract product. In my example below, let's call it IAbility.
Make products inherited from IAbility. I have implemented FireAbility, IceAbility,SlashAbility, and ThrustAbility.
Make an abstract factory. In my case, I'm using IAbilityFactory. This is where the factory method differs from the simple factory. Instead of the concrete implementation of a factory, we now depend on IAbilityFactory.
Create concrete factories that implement IAbilityFactory. Here, these are called ElementalAbilityFactory and PhysicalAbilityFactory.
Now the client can just pass abilityType and get different products from different factories.
The example using the pattern described is shown below.
Abstract Factory
This design pattern works by creating multiple products that belong to the same families using a factory. A single factory is responsible for creating families of the related object without specifying their concrete subclass. One factory should produce at least 2 products that are somehow related to each other. The Design diagram for the abstract factory is shown below.
Example
Let's see an example of a factory method design implementation:
We need to first create at least 2 abstract products that are somehow connected. In my case, they are IPlayer and IAbility.
We then create new concrete products from IPlayer and IAbility. I have fire, ice, slash, and thrust that inherit from IAbility, and Mage, GrandMage, Knight, Lancer that inherit from IPlayer.
Since abstract factory deals with families of objects, it needs to be able to create at least 2 products. In my case, it creates player and ability.
We need to make a concrete implementation of the factory. I have MagicClassFactory and MeleeClassFactory that inherits from ICharacterClassFactory.
Finally, we create ability and player by passing abilityType as a parameter when creating these products.
The example using the pattern described is shown below.
ℹ️
All factories created in my example above always return a product by creating a new object. This is not always true, as you can also use object pooling and provide a product from the pool.
All the above patterns are categorized under creation patterns. These design patterns deal with creating objects.
Hope you learned something new from this. I will be coming up with more design patterns soon.