Factory Method
Defines an interface for creating an object, but lets subclasses decide which class to instantiate.
Context
Your code instantiates concrete classes with new everywhere. When a new variant emerges (another vendor, another format, another channel), you have to touch dozens of files.
Problem
- You couple client code to concrete classes.
- Each new variant requires modifying existing code, violating OCP.
Solution
Move creation to a polymorphic Create method that subclasses override. The client works with the interface and never calls new on the concrete class.
#Structure
Product— interface of the created object.ConcreteProduct— specific implementations.Creator— declares an abstractFactoryMethod()and operates onProduct.ConcreteCreator— returns aConcreteProduct.
#Example in C#
public interface INotification { Task SendAsync(string to, string body); }
public class EmailNotification : INotification
{
public Task SendAsync(string to, string body) => /* SMTP */ Task.CompletedTask;
}
public class SmsNotification : INotification
{
public Task SendAsync(string to, string body) => /* Twilio */ Task.CompletedTask;
}
public abstract class NotificationDispatcher
{
protected abstract INotification Create(); // Factory Method
public Task DispatchAsync(string to, string body) =>
Create().SendAsync(to, body);
}
public class EmailDispatcher : NotificationDispatcher
{
protected override INotification Create() => new EmailNotification();
}
public class SmsDispatcher : NotificationDispatcher
{
protected override INotification Create() => new SmsNotification();
}When NOT to use it
- When you only have one variant and no more are anticipated → it's needless ceremony.
- When you already have DI: a registered
Func<INotification>is often sufficient.
Tradeoffs
| Pro | Con |
|---|---|
| Complies with OCP, variants can be added without touching the client | More classes to maintain |
| Isolates the choice of creation | Can hide real complexity under inheritance |
#Variants
See Parameterized Factory Method (a single creator with enum/string).
#creational #gof #polymorphism