Factory Method - Creational
Overview:
The Factory Method Pattern is an object-oriented design pattern that provides an interface for creating instances of a class but lets subclasses alter the type of objects that will be created. Let's explore its intricacies:
Implementation in C#:
In C#, the Factory Method involves defining an interface for creating objects and letting the subclasses decide which class to instantiate. Here's a simple example:
// Product interface
public interface IProduct
{
void DisplayInfo();
}
// Concrete product
public class ConcreteProductA : IProduct
{
public void DisplayInfo()
{
Console.WriteLine("Product A");
}
}
// Concrete product
public class ConcreteProductB : IProduct
{
public void DisplayInfo()
{
Console.WriteLine("Product B");
}
}
// Creator interface
public interface ICreator
{
IProduct CreateProduct();
}
// Concrete creator
public class ConcreteCreatorA : ICreator
{
public IProduct CreateProduct()
{
return new ConcreteProductA();
}
}
// Concrete creator
public class ConcreteCreatorB : ICreator
{
public IProduct CreateProduct()
{
return new ConcreteProductB();
}
}
Pros:
-
Flexibility: Allows easy extension by adding new product classes without modifying existing code.
-
Encapsulation: Encapsulates object creation logic, promoting a clear separation of concerns.
-
Decoupling: Decouples the client code from the specific classes it instantiates, enhancing maintainability.
Cons:
-
Complexity: Introducing multiple factories and products may increase the complexity of the system.
-
Abstraction Overhead: In simpler scenarios, the pattern might introduce unnecessary abstraction.
When to Use and When Not:
-
Use: When a class cannot anticipate the class of objects it must create, or when a class wants its subclasses to specify the objects it creates.
-
Avoid: In scenarios with simple object creation logic or when the number of products is fixed and unlikely to change.
Usage in .NET Core Framework:
The Factory Method Pattern is prevalent in .NET Core, especially in the ASP.NET Core framework. For instance, the ILoggerFactory in the logging infrastructure uses the factory method pattern to create instances of loggers.
Real-Life Example:
Consider a pizza restaurant where different types of pizzas are created. The PizzaFactory acts as the creator interface, and concrete pizza factories (e.g., HawaiianPizzaFactory, PepperoniPizzaFactory) produce specific pizza types (products).
public interface IPizza
{
void Prepare();
void Bake();
}
public class MargheritaPizza : IPizza
{
// Implementation for Margherita pizza
}
public interface IPizzaFactory
{
IPizza CreatePizza();
}
public class MargheritaPizzaFactory : IPizzaFactory
{
public IPizza CreatePizza()
{
return new MargheritaPizza();
}
}
Register the service with Framework for DI as
// Register IPizzaFactory and IPizza with MargheritaPizzaFactory
services.AddTransient<IPizzaFactory, MargheritaPizzaFactory>();
services.AddTransient<IPizza>(provider =>
{
var factory = provider.GetRequiredService<IPizzaFactory>();
return factory.CreatePizza();
});
In this example, AddTransient is used for both the factory and the pizza. You can adjust the registration method (AddScoped, AddTransient, or AddSingleton) based on your application's requirements.
In conclusion, the Factory Method Pattern in C# empowers flexible object creation. While it offers advantages in flexibility and encapsulation, developers should consider the complexity it introduces and apply it judiciously based on the specific requirements of their application. Understanding when to use or avoid this pattern is crucial for effective and maintainable software design.
No files yet, migration hasn't completed yet!