Factory Pattern explained simply
Factory Pattern
Imagine you want to create objects — but you don't want to expose the creation logic to the client and instead ask a factory class to create objects for you.
That's exactly what the Factory Pattern does.
What is the Factory Pattern?
At its core:
- Defines an interface for creating an object.
- Lets subclasses alter the type of objects that will be created.
- Centralizes object creation, making code more flexible and easier to maintain.
Real-Life Analogy
Think about a bakery:
- You place an order for a "cake".
- You don't worry about how it’s baked.
- The bakery (factory) prepares and gives you the cake.
You simply ask for an object and get it.
Structure
- Product: Common interface for all objects the factory creates.
- Concrete Products: Different implementations of the product interface.
- Creator (Factory): Contains a method that returns objects of the Product type.
Simple Java Example
First, define a Shape
interface:
public interface Shape {
void draw();
}
Concrete implementations:
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Square");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
Create the ShapeFactory:
public class ShapeFactory {
// Factory method
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
Using the Factory
public class MainProgram {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
Shape shape1 = shapeFactory.getShape("CIRCLE");
shape1.draw();
Shape shape2 = shapeFactory.getShape("SQUARE");
shape2.draw();
Shape shape3 = shapeFactory.getShape("RECTANGLE");
shape3.draw();
}
}
Output:
Drawing a Circle
Drawing a Square
Drawing a Rectangle
Why Use the Factory Pattern?
- Encapsulates object creation: Changes to object creation code are centralized.
- Decouples code: Client code depends on abstractions, not concrete classes.
- Easier maintenance and scalability: Add new product types without changing existing client code.
Real-World Use Cases
- GUI Toolkits: Creating buttons, windows, menus.
- Java Libraries:
Calendar.getInstance()
,NumberFormat.getInstance()
. - Database Drivers: Connection creation (
DriverManager.getConnection()
).
Factory Pattern vs. Abstract Factory Pattern
- Factory Pattern: Creates one product type.
- Abstract Factory Pattern: Creates families of related products.
Summary
The Factory Pattern helps you delegate object creation to a separate method or class.
It hides the instantiation details and allows your code to depend on interfaces rather than concrete classes — making it more flexible, robust, and easier to extend.