Instead of creating objects directly using the new keyword, the client delegates object creation to a factory method. This removes the dependency on concrete classes and allows the application to work with abstractions.
The Factory Method Pattern is particularly useful when an application needs to create different implementations of the same interface based on configuration, user input, or business rules.
The pattern is widely used in frameworks, dependency injection, database drivers, logging frameworks, and applications where the exact type of object is determined at runtime.
Structure
The Factory Method Pattern consists of the following participants.1. The Product defines the common interface for all objects created by the factory.
2. Concrete Products provide different implementations of the product interface.
3. The Factory exposes a factory method that creates and returns the appropriate product.
4. The Client requests objects from the factory instead of creating them directly.

Java Implementation
Suppose an application needs to send notifications through different channels such as email and SMS. The client should work with a common interface without knowing which notification service is being created.Create the product interface.
public interface Notification {
void send(String message);
}
Create the concrete products.
public class EmailNotification implements Notification {
@Override
public void send(String message) {
System.out.println("Sending Email: " + message);
}
}
public class SmsNotification implements Notification {
@Override
public void send(String message) {
System.out.println("Sending SMS: " + message);
}
}
Create the factory.
public class NotificationFactory {
public static Notification createNotification(
String type) {
if ("EMAIL".equalsIgnoreCase(type)) {
return new EmailNotification();
}
if ("SMS".equalsIgnoreCase(type)) {
return new SmsNotification();
}
throw new IllegalArgumentException(
"Unsupported notification type.");
}
}
The client requests the required notification service from the factory.
public class Main {
public static void main(String[] args) {
Notification notification = NotificationFactory.createNotification("EMAIL");
notification.send("Order placed successfully.");
}
}
Output:
Sending Email: Order placed successfully.
How It Works?
The client requests a notification object by calling the factory method instead of directly instantiating a concrete class.The NotificationFactory examines the requested notification type and creates the appropriate implementation, such as EmailNotification or SmsNotification.
The factory returns the object as the Notification interface, allowing the client to remain independent of the concrete implementation.
If additional notification channels such as WhatsApp or Push Notifications are introduced, new implementations can be added with minimal changes to the client code.
Advantages
1. It removes the dependency on concrete classes.2. It centralises object creation logic in one place.
3. New product implementations can be introduced without affecting client code.
4. It promotes loose coupling and improves maintainability.
Disadvantages
1. Additional factory classes can increase the number of classes in the application.2. The factory may require modification whenever a new product type is introduced.
3. For simple applications, using a factory may introduce unnecessary complexity.
JDK Examples
The Factory Method Pattern is widely used throughout the Java platform.1. The java.util.Calendar.getInstance() method returns an appropriate Calendar implementation depending on the current locale and configuration.
2. The java.text.NumberFormat.getInstance() method creates a suitable NumberFormat implementation without exposing the concrete class to the client.
Summary
The Factory Method Pattern encapsulates object creation by delegating it to a factory method instead of allowing clients to instantiate concrete classes directly.By separating object creation from object usage, the pattern promotes loose coupling, improves flexibility, and makes applications easier to extend and maintain.