Creational Design Pattern
Factory Method Design Pattern in Java
Define an interface for creating an object and let subclasses decide which concrete object to create.
What is Factory Method?
The Factory Method pattern moves object creation out of client code. A creator class declares a method for creating a product, while concrete creator classes override that method to return a specific product implementation.
The client works with product and creator abstractions instead of directly constructing concrete classes. This makes the code easier to extend when new product types are introduced.
The object creation problem
Direct construction couples an application to a concrete implementation. Every new notification type, payment provider, parser, or report format can force changes in the code that uses it.
public void sendNotification(String type, String message) {
if ("email".equals(type)) {
new EmailNotification().send(message);
} else if ("sms".equals(type)) {
new SmsNotification().send(message);
}
}
This conditional logic works for a small example, but it grows as more product types and creation rules are added.
Factory Method implementation
First, define a product interface and concrete products. The creator owns the workflow and delegates the product creation step to a factory method.
interface Notification {
void send(String message);
}
final class EmailNotification implements Notification {
public void send(String message) {
System.out.println("Email: " + message);
}
}
final class SmsNotification implements Notification {
public void send(String message) {
System.out.println("SMS: " + message);
}
}
Next, define the creator and its concrete creators.
abstract class NotificationService {
protected abstract Notification createNotification();
public void notifyUser(String message) {
Notification notification = createNotification();
notification.send(message);
}
}
final class EmailNotificationService extends NotificationService {
protected Notification createNotification() {
return new EmailNotification();
}
}
final class SmsNotificationService extends NotificationService {
protected Notification createNotification() {
return new SmsNotification();
}
}
The application can now use the creator abstraction while each concrete service decides which notification product to create.
Roles in Factory Method
- Product: Declares the interface implemented by created objects.
- Concrete product: Provides a specific product implementation.
- Creator: Defines the factory method and the common workflow.
- Concrete creator: Overrides the factory method to return a concrete product.
- Client: Uses abstractions instead of constructing concrete products directly.
Advantages and limitations
- Low coupling: Client code depends on product abstractions.
- Open for extension: New products can be added with new creators.
- Centralized workflow: Shared operations remain in the base creator.
- More classes: Each product and creator can add structure to a small project.
- Indirect creation: Developers must follow the creator hierarchy to understand object construction.
When should you use it?
Use Factory Method when a class cannot know in advance which concrete object it should create, when subclasses need to control product creation, or when a creation decision is likely to grow over time. It is common in framework extension points, file parsers, notification providers, payment integrations, and document exporters.