How to Turn C# Factory Method Pattern Into Creation Force


What’s the worst thing you’ve ever done in software development?

I once created a class with many similar methods returning instances of different objects.

It was a pretty bad decision, and now I’m pretty sure that the next time someone asks me about the best method to implement this kind of creation logic, I’m going to say, “Don’t do that.”

For these situations in C#, you should use the Factory Method design pattern.

The Factory Method is a creational design pattern that allows for the abstraction of object creation. It defines a method for creating an object but allows subclasses to determine which object should be created. The type of the instantiated object can be determined during run-time.

When faced with the challenge of designing a simple, elegant, flexible, and reusable data model, you can use the Factory Method pattern. It has proven itself in the real world and is well suited to various problems.

What is the Factory Method design pattern?

The Factory Method is a software design pattern that allows creating objects without exposing the instantiation logic to the client. It defines an interface for creating an object but lets subclasses decide which class to instantiate. It is one of the 23 patterns in the GoF (Gang of Four) book Design Patterns: Elements of Reusable Object-Oriented Software.

The Factory Method design pattern enables a class to defer the instantiation of an object to its subclass.

Factory Method allows you to create the objects without revealing the instantiation logic to the client. Simply put, you create a separate class for building the objects and call that class wherever you need to create an object. It is also known as a Virtual Constructor.

What type of design pattern is the Factory Method?

The Factory Method is the creational design pattern that shows that its purpose is to create something. The creational design patterns are responsible for creating objects using different mechanisms based on the situation. The other creational design patterns used for various purposes are as follows:

Contextual Example

Suppose you have a transport company and are creating an application to manage your business. Initially, you only have transport facilities for people, i.e., Busses, Cars, Van, etc. So, most of your code will lie in the People class. Now, after some time, you plan to expand your business and decide to provide transport facilities to traders who take goods from one place to another. 

Now that most of your code is written to take the people from one place to another and lies in People class, adding Goods will change the entire code.

Similarly, the whole code will change if you decide to transport any other kind of thing in the future. So, in the end, you will have some complex and nasty code, having conditionals that will change the behavior depending upon the class of the objects created.

So, to avoid such a situation, the Factory Method pattern suggests that you should create an abstract class or the interface and create objects using that interface that determines the object’s class based on the parameters.

In the given scenario, you can understand it as follows:

First, you create an interface named Transport that has a method named Transfer. Now create two classes implementing this interface, i.e., People and Goods. Each of these classes implements the Transfer method differently. This way, you will not need to change the entire code to add another type of transport. 

When would you use the Factory Method design pattern?

You should use the Factory Method design pattern in the following situations:

  • You want to minimize code duplication with an interface
  • You need to add more classes quickly without modifying the entire codebase.
  • You want to let subclasses decide which object to create.
  • You want to instantiate an instance of a class by localizing the logic of your program.

Who are the participants of the Factory Method design pattern?

The following UML diagram shows the structure of the Factory Method design pattern.

factory method pattern uml diagram

The participants in the Factory Method pattern are:

  • Product: Defines an interface of objects the factory pattern defines.
  • ConcreteProduct: Implements the Product interface.
  • Creator: The Creator defines the actual Factory Method that will create the objects of the type Product.
  • ConcreteCreator: Overrides the Factory Method to create the objects of ConcreteProduct.

Factory Method – Structural code in C#

Here is the C# code that defines the structure of the Factory method design pattern.

//interface for creating the objects
interface IProduct
{
}

//Concrete Product 1, whose object is created
class ConcreteProduct1 : IProduct
{
}

//Concrete Product 2, whose object is created
class ConcreteProduct2 : IProduct
{
}

//The Creator has a Factory Method.
//This class is actually responsible for creating objects.
abstract class Creator
{
    public abstract IProduct FactoryMethod(int product_number);
}

//Concrete Creator will create the objects
//according to the product number passed to the Factory Method.
class ConcreteCreator : Creator
{
    public override IProduct FactoryMethod(int product_number)
    {
        switch (product_number)
        {
            case 1:
                return new ConcreteProduct1();
            case 2:
                return new ConcreteProduct2();
            default:
                Console.Write("Invalid Product number");
                return null;
        }
    }
}

And the usage:

Creator creator = new ConcreteCreator();
//Product 1
IProduct product = creator.FactoryMethod(1);
//Product 2
IProduct product1 = creator.FactoryMethod(2);
Console.WriteLine("Product:" + product.GetType().Name);
Console.WriteLine("Product:" + product1.GetType().Name);
Console.ReadKey();

Output:

Product:ConcreteProduct1
Product:ConcreteProduct2

Factory Method design pattern in C# with a real-world example

Consider a car selling firm that sells different cars of companies like Honda and Audi.

Suppose the firm uses automated software to show the customer the available vehicles. The firm is doing so well; that more companies want them to sell their cars. In such a situation, the firm owner will have to alter the complete codebase of his car information software to add more cars from other companies. This will increase code duplication, and the code will become nasty and complex. 

So, to avoid such a problem, we will let the interface decide which car to show to the customer based on the parameter passed to the Constructor called at the time of object creation. To understand better, please refer to the following code.

//interface for creating the objects
public interface ICars
{
    string GetName();
    int GetModel();
    string GetColor();
}
//Concrete Product 1, whose object is created
class HondaCars : ICars
{
    public string GetName()
    {
        return "Honda Atlas";
    }
    public int GetModel()
    {
        return 2022;
    }
    public string GetColor()
    {
        return "black";
    }
}
//Concrete Product 2, whose object is created
class AudiCars : ICars
{
    public string GetName()
    {
        return "Audi ABL";
    }
    public int GetModel()
    {
        return 2020;
    }
    public string GetColor()
    {
        return "White";
    }
}
//The Creator has a Factory Method.
//This class is actually responsible for creating objects.
abstract class CarFactory
{
    public abstract ICars FactoryMethod(string Name);
}
//Concrete Creator will create the objects according
//to the product number passed to the Factory Method.
class Factory : CarFactory
{
    public override ICars FactoryMethod(string Name)
    {
        switch (Name)
        {
            case "Honda":
                return new HondaCars();
            case "Audi":
                return new AudiCars();
            default:
                Console.Write("Invalid Product Name");
                return null;
        }
    }
}
class Client
{
    internal static void Main()
    {
        //Creating the creator object using ConcreteCreator
        CarFactory carfactory = new Factory();
        //Product 1
        ICars car1 = carfactory.FactoryMethod("Audi");
        //Product 2
        ICars car2 = carfactory.FactoryMethod("Honda");
        Console.WriteLine("Car 1:" + car1.GetType().Name);
        Console.WriteLine("Name: " + car1.GetName() + "\nModel: " 
            + car1.GetModel() + "\nColor: " + car1.GetColor());
        
        Console.WriteLine("\n\nCar 2:" + car2.GetType().Name);
        Console.WriteLine("Name: " + car2.GetName() + "\nModel: " 
            + car2.GetModel() + "\nColor: " + car2.GetColor());
        
       Console.ReadKey();
    }
}

Output:

Car 1:AudiCars
Name: Audi ABL
Model: 2020
Color: White
Car 2:HondaCars
Name: Honda Atlas
Model: 2022
Color: black

What are the advantages of the C# Factory Method design pattern?

Although all the 23 design patterns proposed by the Gang of Four have different applications, using the Factory Method design pattern gives you the following advantages:

  • Avoids the tight coupling between the Creator and the Concrete products.
  • Subclasses have the choice to choose the type of object to create.
  • The implementation interacts with the interface or the abstract class without directly interacting with the actual classes. This way, it can work with any class that implements that interface or abstract class.
  • Allows adding more products without changing much code.
  • Separates the application from the family of classes.

What are the disadvantages of the C# Factory Method design pattern?

Besides the advantages, the Factory Method design pattern has the following disadvantages:

  • Code becomes difficult to read and understand due to abstraction.
  • Code becomes complex because you create more and more classes to implement the pattern.

What are the three types of the Factory Method?

The three types of Factory Method design patterns are:

  1. Static Factory
  2. Simple Factory
  3. Factory Method

Static Factory Method

The static Factory Method is a public and static method that returns a new instance every time it is called. According to Gang of Four, a class can have a public static method that returns an instance of that class. Simply put, the static Factory Method provides an alternative to the constructors. Instead of a constructor, a class can use the static Factory Method for object instantiation. It can create any type of object. This variant of the Factory Method design pattern is useful when:

  • You want to give meaningful names to the method that creates your objects.
  • You want to avoid complex object creation.
  • You want to limit the caching.

Example:

public class Vehicle
{
    string _vehicleType;
    string _name;
    public Vehicle(string vehicle_type, string name)
    {
        _vehicleType = vehicle_type;
        _name = name;
    }
    //static factory
    public static Vehicle GetVehicle(string type, string name)
    {
        return new Vehicle(type, name);
    }
    public void PrintVehicle()
    {
        Console.WriteLine("Type: " + _vehicleType + " \nName: " + _name);
    }
}

Usage:

Vehicle vehicle = Vehicle.GetVehicle("Car", "Mustang");
vehicle.PrintVehicle();
Console.ReadKey();

Output:

Type: Car
Name: Mustang

Simple Factory

A simple factory variant of a Factory Method design pattern can be defined as a tool to create or instantiate an object. It is neither a Factory Method pattern nor an Abstract Factory pattern. It is usually the same as the static factory pattern. The only difference between this and the static factory is that it is non-static.

A simple factory usually doesn’t implement a factory interface. It hides the object creation logic. 

Example:

public interface Vehicle
{
    public void GetVehicleType();
}
public class Car : Vehicle
{
    public void GetVehicleType()
    {
        Console.WriteLine("Car");
    }
}
public class Truck : Vehicle
{
    public void GetVehicleType()
    {
        Console.WriteLine("Truck");
    }
}
public class Aeroplane : Vehicle
{
    public void GetVehicleType()
    {
        Console.WriteLine("Airplane");
    }
}
// Simple Factory
public class TruckFactory
{
    public Truck GetTruck()
    {
        return new Truck();
    }
}

Usage:

//Instantiating the factory
TruckFactory truck = new TruckFactory();
//creating the objects using factory
Truck truck1 = truck.GetTruck();
truck1.GetVehicleType();
Console.ReadKey();

Output:

Truck

Factory Method

The Factory Method pattern implies that an interface should create the objects, and the subclasses should decide which class to instantiate. It separates the code dependent upon the interface of the object and the process of object creation. The Factory Method depends on abstraction instead of concrete classes in this pattern.

The difference from the simple factory implementation: this time, there is a VehicleFactory interface that every concrete factory class implements.

Example:

public interface Vehicle
{
    public void GetVehicleType();
}
public class Car : Vehicle
{
    public void GetVehicleType()
    {
        Console.WriteLine("Car");
    }
}
public class Truck : Vehicle
{
    public void GetVehicleType()
    {
        Console.WriteLine("Truck");
    }
}
public class Aeroplane : Vehicle
{
    public void GetVehicleType()
    {
        Console.WriteLine("Airplane");
    }
}
//creating the interface
public interface VehicleFactory
{
    public Vehicle GetVehicle();
}
//implementing the factory with ConcreteTruckFactory
public class ConcreteTruckFactory : VehicleFactory
{
    //Actual factory method
    public Vehicle GetVehicle()
    {
        return new Truck();
    }
}

Usage:

// instantiating the Factory
VehicleFactory truckFactory = new ConcreteTruckFactory();
//creating objects using Factory method
var truck = truckFactory.GetVehicle();
truck.GetVehicleType();
Console.ReadKey();

Output:

Truck

Dependency Injection vs. Factory Pattern

dependency injection small

The dependency injection and factory pattern might seem similar, as they are different solutions to the same problem, i.e., object creation. But, there are differences between both. The main difference is how you obtain the object reference.

In dependency injection, as its name depicts, you get the object reference from outside the code. In other words, the reference gets injected into your code. In the Factory pattern, your code requests the reference, so it fetches the object. Both dependency injection and the factory pattern decouple the link code and underlying class, but each does that differently.

You can also call the Factory Method pattern a tool to implement the dependency injection. When you use the Factory Method, your code is responsible for creating the objects, whereas, in dependency injection, you give the responsibility of object creation to another class outside of your code.

Is the Factory Method useful while refactoring?

Factory methods are useful while refactoring because they allow you to create new objects without having to change the code in the class that uses them. This can be helpful if you want to change how objects are created but don’t want to change the code in the class that needs them.

The following two refactorings benefit from the Factory Method.

Replacing constructors with Factory Method

Suppose you have a code in which the constructors create the objects, and the values of the coded types are passed to the constructors to instantiate the object.

The problem is that you will have to define a separate constructor for each class responsible for initializing the objects. Now, if you refactor the code and add a static method that takes in the type of the object to be created as a parameter and instantiates the classes based on the passed type, you will save yourself from defining many constructors.

It is impossible to change the original constructors to make them return subclass objects, so instead, you can declare a static Factory Method that returns the object of called class. Once created, the Factory Method will replace all the calls to the original constructors.

Replacing conditionals with polymorphism

This refactoring technique is helpful when you have conditionals in your code that perform various tasks based on the object type, object properties, and the result of calling any of the object’s methods.

The following video explains the Replace conditional with polymorphism refactoring in C#.

Suppose you have a code somewhat similar to the above-stated car scenario. Now, if a new object type or property appears, you will have to search for all the similar conditionals and add code to it.

So, instead of using conditionals, you can refactor your code by creating the subclasses for every branch of the conditional. In each subclass, add a common method but change its implementation based on the corresponding branch in the conditional. By replacing the conditional with the relevant method call, you will attain proper implementation via polymorphism depending on the object’s class. This refactoring technique is beneficial when multiple conditionals are scattered throughout the object’s methods.

Conclusion

The Factory Method design pattern lets you leave the type of created object on the subclasses.

It enables you to define an interface through which the client will create the object. Its main purpose is to hide the object creation logic from the client. It is also known as a virtual constructor.

This design pattern can save you from writing the same code repetitively. You can use it to replace the constructors and conditionals in your code. In this article, you will find all the details about the Factory Method design pattern, including its structural code and real-world implementation.

FAQ

faq

What are the differences between the Abstract Factory and Factory Method Design Patterns?

The major difference between the Abstract Factory and the Factory Method design pattern is that the Factory Method is a single method responsible for creating the objects. In contrast, an abstract factory is an object with multiple Factory Methods.

What is the difference between the Factory Method and Prototype design pattern?

The Factory Method is responsible for instantiating the objects while hiding the instantiation logic from the client. It introduces loose coupling between objects. You use the Prototype pattern to avoid unnecessary object creation when the cost of creating the objects is high, and you can use an existing copy of the object.

Why use the Factory Method instead of the Constructor?

First, the Factory Method is mostly implemented because it allows long-term flexibility and a more decoupled and testable design. Constructors are a good choice to use when they contain simple code, but when it comes to complex constructors, consider implementing a Factory Method to avoid code replication. 

Is Factory Method always static?

The Factory method doesn’t have to be always static. The purpose of this pattern is to have an object responsible for creating the objects of another class. How you do it depends upon you. It can be static or non-static. However, the typical mechanism is to use a static method in a class.

Recent Posts