The Factory design pattern is a creational design pattern that provides an interface for creating objects without specifying their concrete classes. It encapsulates the object creation logic in a separate class or method, known as the factory, which is responsible for creating instances of different types based on certain conditions or parameters.
The Factory pattern allows for flexible object creation, decoupling the client code from the specific implementation of the created objects. It promotes code reuse and simplifies the process of adding new types of objects without modifying the existing client code.
There are several variations of the Factory pattern, including the Simple Factory, Factory Method, and Abstract Factory. Here's a brief explanation of each:
-
Simple Factory: In this variation, a single factory class is responsible for creating objects of different types based on a parameter or condition. The client code requests objects from the factory without being aware of the specific creation logic.
-
Factory Method: In the Factory Method pattern, each specific type of object has its own factory class derived from a common base factory class or interface. The client code interacts with the base factory interface, and each factory subclass is responsible for creating a specific type of object.
-
Abstract Factory: The Abstract Factory pattern provides an interface for creating families of related or dependent objects. It defines a set of factory methods that create different types of objects, ensuring that the created objects are compatible and consistent. The client code interacts with the abstract factory interface to create objects from the appropriate family.
Here's a simple example to illustrate the Factory Method pattern in C#:
// Product interface public interface IProduct { void Operation(); } // Concrete product implementation public class ConcreteProduct : IProduct { public void Operation() { Console.WriteLine("ConcreteProduct operation"); } } // Factory interface public interface IProductFactory { IProduct CreateProduct(); } // Concrete factory implementation public class ConcreteProductFactory : IProductFactory { public IProduct CreateProduct() { return new ConcreteProduct(); } } // Client code public class Client { private readonly IProductFactory _factory; public Client(IProductFactory factory) { _factory = factory; } public void UseProduct() { IProduct product = _factory.CreateProduct(); product.Operation(); } }
In this example, IProduct
is the product interface that defines the common operation that products should implement. ConcreteProduct
is a specific implementation of IProduct
.
The IProductFactory
interface declares the factory method CreateProduct
, which returns an IProduct
object. ConcreteProductFactory
is a concrete factory that implements the IProductFactory
interface and creates instances of ConcreteProduct
.
The Client
class depends on an IProductFactory
and uses it to create and interact with the product. The client code is decoupled from the specific implementation of the product and the creation logic, allowing for flexibility and easier maintenance.
Overall, the Factory design pattern enables flexible object creation and promotes loose coupling between the client code and the object creation process. It's particularly useful when you anticipate variations in object creation or want to abstract the creation logic from the client code.