Design patterns are proven solutions to software design problems. They help improve code quality, promote reusability, and increase maintainability. We use them to save time and produce quality, extensible and flexible code. In this article, we are going to introduce the Factory design pattern.
The Factory pattern is a creational pattern that provides an interface to create objects for a super class, but allows derived classes to change the type of objects that are created. This pattern delegates object creation to derived classes.
The factory pattern is useful when a common interface is needed to create objects, but the actual classes created may be different. This pattern separates classes and their constructors well and creates high flexibility in creating objects.
The factory pattern includes the following components:
Below is an example of the factory pattern in C# language:
// Product interface
public interface ILogger
{
void Log(string message);
}
// Concrete product classes
public class FileLogger : ILogger
{
public void Log(string message)
{
// Code to log message to a file
}
}
public class DatabaseLogger : ILogger
{
public void Log(string message)
{
// Code to log message to a database
}
}
// Creator abstract class
public abstract class LoggerFactory
{
public abstract ILogger CreateLogger();
}
// Concrete creator classes
public class FileLoggerFactory : LoggerFactory
{
public override ILogger CreateLogger()
{
return new FileLogger();
}
}
public class DatabaseLoggerFactory : LoggerFactory
{
public override ILogger CreateLogger()
{
return new DatabaseLogger();
}
}
// Usage code
class Program
{
static void Main(string[] args)
{
// Use the factory method to create a logger
LoggerFactory loggerFactory = new FileLoggerFactory();
ILogger logger = loggerFactory.CreateLogger();
logger.Log("Log message");
loggerFactory = new DatabaseLoggerFactory();
logger = loggerFactory.CreateLogger();
logger.Log("Log message");
}
}
In this example, we have an ILogger interface that defines the logging method signature. Then we have two related classes that implement this interface: FileLogger and DatabaseLogger
The LoggerFactory abstract class will be the template for other constructor classes. This class has a method for creating objects that must be implemented by derived classes and returns an ILogger object.
FileLoggerFactory and DatabaseLoggerFactory classes are classes that inherit from the original LoggerFactory class and implement the CreateLogger method. Each of these constructors creates and returns its own objects.
Then we use all the created classes in the Main function. First, we create a LoggerFactory object and use its CreateLogger method to create an ILogger object. Regardless of which LoggerFactory derivative we use to create the ILogger object, we can use the ILogger object to log to a file or a database.
Studying this pattern is not only for the purpose of using it. This pattern has been used in different frameworks, knowing how it works helps us in using these frameworks.
To read about other design patterns, you can use the list below. There is also a code repository on GitHub that includes all the design patterns.
I am Reza Babakhani, a software developer. Here I write my experiences, opinions and suggestions about technology. I hope that what I write is useful for you.
leave a comment