Factory Method

Factory Method

Design patterns are essential tools in a software developer's toolkit, offering proven solutions to common problems encountered in software design and development. In this series, we will explore various design patterns, providing detailed explanations, code examples, and practical insights into their usage.

This article marks the starting point of our journey, focusing on creational design patterns, which address the process of object creation in software systems. We'll start by exploring the Factory Method pattern—a versatile and widely used pattern that facilitates flexible object creation mechanisms.

I created a solution in my GitHub that contains a project called FactoryMethod for this article. You can find it here:

https://github.com/amirdoosti6060/DesignPatterns

Why do we need design patterns?

Design patterns provide proven solutions to frequent design problems in software development. They encapsulate best practices, promote code reusability, and facilitate communication among developers. Ultimately, design patterns help create more maintainable, flexible, and scalable software systems.

What are Creational Design Patterns?

Creational design patterns are a category of design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. Creational patterns provide various mechanisms for object creation, encapsulation, and decoupling of the creation process from the client code. These patterns help to make a system independent of how its objects are created, composed, and represented.

List of Creational Design Patterns

Here are some common creational design patterns and a very short description for each one that helps you to remember them easily:

  • Factory Method: Define an interface for creating objects, but let subclasses decide which class to instantiate.
  • Abstract Factory: Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
  • Singleton: Ensure a class has only one instance and provide a global point of access to that instance.
  • Builder: Separate the construction of a complex object from its representation, allowing the same construction process to create different representations.
  • Prototype: Create new objects by copying an existing object, known as a prototype, rather than creating new instances from scratch.

Here's a mnemonic sentence to help remember those five design patterns:

"Five Awesome Design Patterns Bring Success"

Each word in the sentence corresponds to one of the design patterns:

  • "Five" for Factory Method
  • "Awesome" for Abstract Factory
  • "Patterns" for Prototype
  • "Bring" for Builder
  • "Success" for Singleton

Factory Method

The Factory Method Design Pattern is a creational pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. It encapsulates object creation logic, promoting loose coupling and flexibility in object instantiation. 

1. Overview of the Factory Method Pattern

The Factory Method pattern defines an interface for creating objects but delegates the actual creation to subclasses. It's useful when you have a superclass that can't anticipate the exact class of objects it needs to create. Instead, it defers object instantiation to subclasses, which can override the factory method to produce objects of different types.

2. Structure of the Factory Method Pattern

  • Product: Defines the interface for objects created by the factory method.
  • ConcreteProduct: Implements the Product interface.
  • Creator: Declares the factory method, which returns an instance of a Product. It may also provide a default implementation of the factory method.
  • ConcreteCreator: Overrides the factory method to return a specific instance of ConcreteProduct.

Note that not all Factory Method implementations have all four parts. Later I’ll provide you some examples of existing Factory Methods in .NET. 

3. Implementation in C#

Let's demonstrate the Factory Method pattern with a simple example of creating different types of vehicles: Car and Truck.

// Product interface
public interface IVehicle
{
    void Drive();
}

// ConcreteProduct: Car
public class Car : IVehicle
{
    public void Drive()
    {
        Console.WriteLine("Driving a car...");
    }
}

// ConcreteProduct: Truck
public class Truck : IVehicle
{
    public void Drive()
    {
        Console.WriteLine("Driving a truck...");
    }
}

// Creator interface
public interface IVehicleFactory
{
    IVehicle CreateVehicle();
}

// ConcreteCreator: CarFactory
public class CarFactory : IVehicleFactory
{
    public IVehicle CreateVehicle()
    {
        return new Car();
    }
}

// ConcreteCreator: TruckFactory
public class TruckFactory : IVehicleFactory
{
    public IVehicle CreateVehicle()
    {
        return new Truck();
    }
}        

4. Usage of the Factory Method Pattern

class Program
{
    static void Main(string[] args)
    {
        var carFactory = new CarFactory();
        var truckFactory = new TruckFactory();

        Client(carFactory);
        Client(truckFactory);
    }

    void Client(IVehicleFactory vehicleFactory)
    {
        IVehicle vehicle = vehicleFactory.CreateVehicle();
        vehicle.Drive();
    }
}        

In this usage, the Client method doesn’t have any idea about the type of vehicle that should be created and it is decoupled from the specific product.

We create a factory for a specific product and pass it to the client method then it can create an appropriate product and use it (Drive method).

5. Benefits of the Factory Method Pattern

  • Encapsulation: Encapsulates object creation logic in a separate class, promoting loose coupling between the creator and the product.
  • Flexibility: Allows subclasses to alter the type of objects created without modifying the client code.
  • Testability: Facilitates unit testing by isolating object creation logic from the rest of the application.

6. When to Use the Factory Method Pattern:

  • Use the Factory Method pattern when you have a superclass that can't anticipate the class of objects it needs to create.
  • Use it when you want to delegate object creation to subclasses to provide flexibility and customization.

Existing Factory Method in .NET

It might be interesting for you to know where the Factory Method is used in .NET. Here are five examples of the Factory Method pattern in .NET along with explanations of why they qualify as Factory Methods. All of them do not include all the components of the Factory Method, but they use the same concept:

1. System.Data.Common.DbProviderFactory

  • Creator Interface: System.Data.Common.DbProviderFactory
  • Product Interface: System.Data.Common.DbConnection
  • Creator Concrete: System.Data.SqlClient.SqlClientFactory, System.Data.OleDb.OleDbFactory, etc.
  • Product Concrete: System.Data.SqlClient.SqlConnection, System.Data.OleDb.OleDbConnection, etc.

Explanation: The DbProviderFactory abstract class defines a factory method, CreateConnection(), which returns an instance of DbConnection. Concrete implementations like SqlClientFactory and OleDbFactory override this method to create specific types of database connections (SqlConnection, OleDbConnection, etc.), making it a classic example of the Factory Method pattern.

2. System.Xml.Serialization.XmlSerializer

  • Creator Interface: System.Xml.Serialization.XmlSerializer
  • Product Interface: None
  • Creator Concrete: System.Xml.Serialization.XmlSerializer
  • Product Concrete: None

Explanation: XmlSerializer acts as both the creator and the product in this scenario. It provides a factory method, CreateSerializer(), which returns an instance of XmlSerializer. While it doesn't have a separate product interface, it still follows the Factory Method pattern by encapsulating the creation logic for XML serializers.

3. System.Net.WebRequest

  • Creator Interface: System.Net.WebRequest
  • Product Interface: None
  • Creator Concrete: System.Net.HttpWebRequest, System.Net.FileWebRequest, etc.
  • Product Concrete: None

Explanation: WebRequest is an abstract class with a factory method, Create(), which returns an instance of WebRequest. Concrete implementations like HttpWebRequest and FileWebRequest override this method to create specific types of web requests, adhering to the Factory Method pattern.

4. System.Net.Sockets.Socket

  • Creator Interface: None
  • Product Interface: None
  • Creator Concrete: None
  • Product Concrete: System.Net.Sockets.Socket

Explanation: While Socket doesn't have separate creator and product interfaces, it serves as both the creator and the product. The static factory methods like Socket.Create() and Socket.Accept() are responsible for creating and returning instances of Socket, following the principles of the Factory Method pattern.

5. System.IO.File

  • Creator Interface: None
  • Product Interface: None
  • Creator Concrete: None
  • Product Concrete: System.IO.File

Explanation: Similar to the Socket class, the File class in System.IO doesn't have separate creator and product interfaces. However, methods like File.Create() and File.Open() act as factory methods that create and return instances of File, making it another example of the Factory Method pattern in .NET.


Conclusion

In conclusion, the Factory Method Design Pattern is a valuable tool for decoupling object creation logic from client code, promoting flexibility and maintainability in object-oriented systems. By encapsulating object creation in a separate method, the Factory Method pattern facilitates easy extension and customization of object creation processes.

#csharp #dotnet #designpatterns #factorymethod


To view or add a comment, sign in

More articles by Amir Doosti

  • Modern Thread Communication in C#

    Managing communication between threads is a fundamental challenge in modern software development. Historically…

  • Impersonation

    Impersonation in C# What is impersonation? Impersonation is a security mechanism that allows your code to execute under…

    2 Comments
  • Span<T> and Memory<T> in C#

    Modern .NET and C# put a huge emphasis on high performance with minimal allocations.

  • Network Programming in c# - Part 2 (HTTP programming)

    In the previous article I talked about Socket programming. Today, I’m going to cover another type of network…

  • Network Programming in C# - Part 1

    Network programming in C# involves using .NET libraries to communicate between systems over a network.

    2 Comments
  • Locking (Synchronization) in C#

    Concurrency and multithreading are powerful features in modern programming, but they bring challenges, especially in…

    6 Comments
  • Plotting in C# (Part 4 - ScottPlot)

    ScottPlot is an open-source, .NET-based charting library designed for creating high-performance, interactive plots in…

  • Plotting in C# (Part 3 - OxyPlot)

    OxyPlot is a lightweight, open-source plotting library designed specifically for .NET applications, supporting…

    2 Comments
  • Plotting in C#.Net (Part2 - LiveCharts2)

    LiveCharts is a versatile and modern charting library that supports a variety of charts and visualizations with smooth…

  • Plotting in C#.Net (Part 1 - General)

    Plotting is a crucial tool for data analysis, visualization, and communication. There are many reasons why we need to…

    2 Comments

Others also viewed

Explore content categories