Java Factory Pattern
In this page:
What is the Factory Pattern?
The Factory Pattern defines an interface, or an abstract method, for creating an object, but lets subclasses decide exactly which concrete class actually gets instantiated. This keeps the calling code working purely against the interface, with no knowledge of which implementation it ultimately receives.
Example: What is the Factory Pattern?
public class Main {
interface Shape {}
static class Circle implements Shape {}
interface ShapeFactory { Shape create(); }
public static void main(String[] args) {
ShapeFactory factory = Circle::new; // caller only knows the interface
Shape shape = factory.create();
System.out.println(shape.getClass().getSimpleName());
}
}
Login to try C/C++/Java/PHP code in the editor
Polymorphic Factory Method
By implementing a factory method inside an abstract class and leaving it abstract there, each subclass can override that method to specify which concrete class gets created for its particular variant, letting the object-creation logic vary polymorphically alongside the rest of the subclass's behavior.
Example: Polymorphic Factory Method
public class Main {
static abstract class Dialog {
abstract Object createButton(); // subclasses decide the concrete type
}
static class WindowsDialog extends Dialog {
Object createButton() { return "WindowsButton"; }
}
public static void main(String[] args) {
Dialog dialog = new WindowsDialog();
System.out.println(dialog.createButton());
}
}
Login to try C/C++/Java/PHP code in the editor
Parameterized Factory Method
You can parameterize a factory so it returns different object types based on an input value, such as a type code or name, rather than needing a separate factory method for every variant. Using an enum for that parameter, rather than a raw String or int, is strongly recommended since it catches invalid values at compile time.
Example: Parameterized Factory Method
public class Main {
enum ShapeType { CIRCLE, SQUARE }
static Object createShape(ShapeType type) {
return switch (type) { // enum catches invalid values at compile time
case CIRCLE -> "Circle";
case SQUARE -> "Square";
};
}
public static void main(String[] args) {
System.out.println(createShape(ShapeType.SQUARE));
}
}
Login to try C/C++/Java/PHP code in the editor
Benefits of Decoupling
The Factory Pattern's core benefit is decoupling client code from the exact classes it depends on being instantiated. Clients are shielded from object-creation complexity entirely, whether that complexity is choosing between subclasses, reading configuration, or wiring up dependencies.
Example: Benefits of Decoupling
public class Main {
interface Notifier { void send(String msg); }
static class EmailNotifier implements Notifier {
public void send(String msg) { System.out.println("Email: " + msg); }
}
static Notifier createNotifier() { return new EmailNotifier(); } // client shielded from creation details
public static void main(String[] args) {
Notifier n = createNotifier();
n.send("Hello");
}
}
Login to try C/C++/Java/PHP code in the editor
Real-World Use Cases
Factories show up constantly in real systems: loading a database connection configured by a settings file, choosing a communication protocol implementation at runtime, or picking a specific notification channel (email, SMS, push) based on user preference are all natural fits for this pattern.
Example: Real-World Use Cases
public class Main {
interface Notifier { void send(String msg); }
static class SmsNotifier implements Notifier {
public void send(String msg) { System.out.println("SMS: " + msg); }
}
static class EmailNotifier implements Notifier {
public void send(String msg) { System.out.println("Email: " + msg); }
}
static Notifier getNotifier(String preference) {
return preference.equals("sms") ? new SmsNotifier() : new EmailNotifier();
}
public static void main(String[] args) {
getNotifier("sms").send("Order shipped");
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first:
- Java Design Patterns Introduction
- Java Singleton Pattern
- Java Factory Pattern
- Java Observer Pattern
- Java Builder Pattern
- Java MVC Architecture
- Java Adapter Pattern
- Java Decorator Pattern
- Java Strategy Pattern
- Java Command Pattern
- Java Facade Pattern
- Java Proxy Pattern
- Java Template Method Pattern
- Java Repository Pattern