Learn how the Factory Method pattern helps create flexible, decoupled object instantiation in your .NET apps.
📌 What is the Factory Method Pattern?
The Factory Method pattern is a creational design pattern that defines an interface (or abstract method) for creating an object, but lets subclasses decide which class to instantiate. It decouples client code from object creation logic—perfect when your system needs to support multiple product types or dynamic creation at runtime.
🤔 When to Use It
Use Factory Method when:
- You want to delegate object creation to subclasses.
- There are multiple product types selected by configuration or runtime data.
- You want to follow SOLID principles like DIP and OCP.
Common scenarios include plug-in architectures, UI element generation (buttons, dialogs), and different notification types.
🧩 Pattern Components
The pattern typically involves:
- Product – The interface or abstract class that defines common behaviors.
- ConcreteProduct – Implementations of the Product interface.
- Creator – Declares the factory method, can also define a default implementation.
- ConcreteCreator – Implements the factory method to return a ConcreteProduct.
🖋 Example: Notification System
Let's implement a flexible notification system that sends different message types.
// 1. Product Interface
public interface INotification {
void Send(string recipient, string message);
}
// 2. Concrete Products
public class EmailNotification : INotification {
public void Send(string r, string m) =>
Console.WriteLine($"Email: To={r}, Msg={m}");
}
public class SmsNotification : INotification {
public void Send(string r, string m) =>
Console.WriteLine($"SMS: To={r}, Msg={m}");
}
// 3. Creator
public abstract class NotificationCreator {
public abstract INotification CreateNotification();
public void Notify(string recipient, string message) {
var note = CreateNotification();
note.Send(recipient, message);
}
}
// 4. Concrete Creators
public class EmailCreator : NotificationCreator {
public override INotification CreateNotification() =>
new EmailNotification();
}
public class SmsCreator : NotificationCreator {
public override INotification CreateNotification() =>
new SmsNotification();
}
🚀 Usage at Runtime
static void Main() {
NotificationCreator creator;
// Switch based on config, user preference, etc.
string type = "email";
creator = (type == "sms") ? new SmsCreator() : new EmailCreator();
creator.Notify("[email protected]", "Hello from Factory Method!");
}
The client code only deals with NotificationCreator and INotification, keeping it decoupled from concrete implementations.
✅ Benefits
Loose coupling: Client code never needs to know concrete types.
Open for extension: Add new creators/products without modifying existing systems—follows OCP.
Subclass-specific logic: Additional setup/configuration can occur in Concrete Creators before returning objects.
⚠️ Common Pitfalls & Best Practices
Pitfall ** ** Solution
Overuse Apply only where variability or decoupling is needed
Over-reliance on config Use safe defaults or factory chaining
Breaking DIP Use interfaces and dependency injection
🛠 Real‐World Scenarios
Payment gateway selection (PayPal, Stripe, etc.)
UI control creation (WinForms, Web UI, mobile buttons)
Loggers or file handlers chosen at runtime
Unit testing with mock implementations
🧑🏫 UML Overview
Creator
+ Notify()
+ CreateNotification() → INotification
↳ EmailCreator
↳ SmsCreator
INotification ⟶ EmailNotification, SmsNotification
🧠 How It Relates to SOLID
DIP: Client code depends on INotification, not concrete types.
OCP: Extend with new creators without changing existing code.
LSP: All concrete creators and products can replace their base types seamlessly.
🏁** Summary**
The Factory Method pattern empowers .NET developers to:
Decouple object creation logic from usage
Configure behavior dynamically
Write scalable, testable, and maintainable code
Look for repeated new keywords and rigid switch statements—they're often signs that Factory Method might be a better solution.
🔧 Further Reading
Refactoring.Guru – Factory Method
Microsoft Docs – Design Patterns
HackerNoon – Benefits of Using Factory Pattern in .NET
If you found this post helpful, give it a ❤️ or share your own Factory Method use cases below!
Top comments (0)