In class-based programming, the factory method pattern is a creational pattern which uses factory methods to deal with the problem of creating objects without specifying the exact class of object that will be created. This is done by creating objects via a factory method, which is either specified in an interface (abstract class) and implemented in implementing classes (concrete classes); or implemented in a base class (optionally as a template method), which can be overridden when inherited in derived classes; rather than by a constructor.
- When we want to encapsulate/hide the logic from clients who use it.
- When we are producing families of the same type.
- When a system should be independent of how its products are created, composed and represented.
- When we want to avoid series of if statements, switch and new keywords on the client.
- Maintainability, low coupling, and high cohesion.
In this example we will create an AnimalFactory that implements IAnimal interface. For the purpose of demonstration let us keep this simple. The interface has a method of Talk() that will just display how the animal talks on the console.
The Source Code
The Project Structure
The IAnimal Interface
This defines the contract to be use by the Animals class.
IAnimal.cs
The Animal Factory
This is the factory that decides what kind of animal will be created and pass it to the client. It sets between the client and the animal classes.
AnimalFactory.cs
The Animal Classes
These are the classes that implements the IAnimal interface. These classes might grow large so that the approach in the Animal Factory is not suitable in large project. A better approach is by using reflection which I will be discussing later.
Dog.cs
Cat.cs
Cat.cs
I will only show 2 classes here because the rest are the same.
The Client Program
In the client, we can now instantiate Animal Factory and use the methods through IAnimal interface.
Program.cs
The Problems in this approach:
We can use reflection to solve this problem. Loop through the executing assembly and check if the class exist, then create the instance.
Don't Forget these:
Instead of using AnimalFactory.cs, use AnimalFactoryUsingReflection.cs.
AnimalFactoryUsingReflection.cs
In the client program, disregard the AnimalFactory.
Program.cs
The Client Program
In the client, we can now instantiate Animal Factory and use the methods through IAnimal interface.
Program.cs
The Problems in this approach:
- We did not eliminate the use of switch keyword.
- When a new class will be added in the future, we need to add more case statement in the AnimalFactory class, thus violating the Open Closed Principle.
We can use reflection to solve this problem. Loop through the executing assembly and check if the class exist, then create the instance.
Don't Forget these:
- Put the class in one folder. In this example, the folder is Animals.
- Be sure to convert the class name to lowercase before using it.
Instead of using AnimalFactory.cs, use AnimalFactoryUsingReflection.cs.
AnimalFactoryUsingReflection.cs
In the client program, disregard the AnimalFactory.
Program.cs