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:
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:
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:
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
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.
Recommended by LinkedIn
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
6. When to Use the Factory Method Pattern:
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
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
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
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
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
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