Overview
The Factory Method pattern moves object creation into a dedicated method, so client code asks for an object by intent rather than calling new on a concrete class. The client depends on an interface; the factory decides which implementation to build.
Factories centralize construction logic, hide complex setup, and make it easy to add new types. They pair naturally with Strategy: the factory selects the strategy, and the context uses it.
You order a latte; you do not grind beans or steam milk yourself. The barista knows how to make each drink. Adding a new drink to the menu does not change how you order.
When to use it
- Code calls new ConcreteClass() in many places, making it hard to swap implementations.
- The exact type depends on configuration, input, or environment.
- Construction is complex: dependencies, validation, or caching of instances.
Where it shows up in interviews
Recognize it when: new X based on input or configuration.
- Design a notification service
- Design a document parser for PDF/CSV/JSON
Recognize it when: subclasses decide which object to create.
- Design a logging framework
- Design a UI toolkit
Where it is used in real software
Static factories return locale-specific implementations.
Returns a vendor-specific connection behind the Connection interface.
A factory that creates elements of any component type.
Key terms
- Product
- The interface the factory returns, such as Notification.
- Concrete product
- A specific implementation such as EmailNotification.
- Creator / factory
- The class or function that decides which product to build.
How it works, step by step
- 1Define the product interface
Clients will depend only on this type.
- 2Implement concrete products
Each implements the interface.
- 3Write the factory
A method that takes the selection input and returns the product interface.
- 4Replace direct constructors
Clients call the factory instead of new.
Notification channels
User preference decides the channel
| Input | Factory returns | Client calls |
|---|---|---|
| EmailNotification | notification.send(message) | |
| sms | SmsNotification | notification.send(message) |
| push | PushNotification | notification.send(message) |
NOWInput: email | Factory returns: EmailNotification | Client calls: notification.send(message)
The client code is identical for every channel. Adding WhatsApp means one new class and one registry entry.
Implementation
interface Notification { send(to: string, message: string): Promise<void>;} class EmailNotification implements Notification { async send(to: string, message: string) { /* SMTP */ }}class SmsNotification implements Notification { async send(to: string, message: string) { /* SMS gateway */ }} type Channel = "email" | "sms"; const registry: Record<Channel, () => Notification> = { email: () => new EmailNotification(), sms: () => new SmsNotification(),}; function createNotification(channel: Channel): Notification { return registry[channel]();} await createNotification(user.preferredChannel).send(user.contact, "Your order shipped");Complexity and performance
Plus one lookup or call.
Trade-offs
For one concrete class that will not change, a factory adds indirection without benefit.
A giant switch in the factory is still better than switches everywhere, but a registry map keeps it open for extension.
Variants and related techniques
A single function with a switch or map. Most common in practice.
An overridable method in a base class; subclasses choose the product.
Creates families of related products that must be used together, such as a matching button, checkbox, and menu for one theme.
Common mistakes
- Returning concrete types from the factory.
Fix: Return the interface, or clients will couple to implementations again.
- Factories that also perform business logic.
Fix: Factories construct objects; the objects do the work.
Interview questions
Factory Method vs Abstract Factory?
Factory Method creates one product and is often varied by subclassing. Abstract Factory creates a family of related products through one interface.
Factory vs dependency injection?
DI supplies dependencies from outside at wiring time. Factories create objects on demand at runtime based on input. They are often used together.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| Shape factory | Easy | Return shapes by name. |
| Document parser factory | Medium | Choose PDF, DOCX, or HTML parser by extension. |