Factory Design Pattern

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 to Use:
  • 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.
Let’s jump to the code!

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
Download 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

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 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.
Solution:

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:
  1. Put the class in one folder. In this example, the folder is Animals.
  2. 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