DEV Community

Vivek Kurmi
Vivek Kurmi

Posted on • Edited on

Factory Pattern

The Factory Method Pattern is a creational design pattern that provides an interface for creating objects but allows subclasses to alter the type of objects that will be created. It promotes loose coupling between the creator (factory) and the objects it creates, making it a flexible way to create objects. Let's explain the Factory Method Pattern in Java with a simple example:

Example: Creating Shapes

Suppose you are building a drawing application, and you want to create different types of shapes, such as circles and rectangles. Instead of creating these shapes directly in your code, you can use the Factory Method Pattern to create them through a factory.

Here's how you can implement it:

  1. Define an interface for the shape:
// Shape.java
public interface Shape {
    void draw();
}
Enter fullscreen mode Exit fullscreen mode
  1. Create concrete classes that implement the shape interface:
// Circle.java
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

// Rectangle.java
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Rectangle");
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Create a factory interface that declares the factory method:
// ShapeFactory.java
public interface ShapeFactory {
    Shape createShape();
}
Enter fullscreen mode Exit fullscreen mode
  1. Implement concrete factories for each type of shape:
// CircleFactory.java
public class CircleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Circle();
    }
}

// RectangleFactory.java
public class RectangleFactory implements ShapeFactory {
    @Override
    public Shape createShape() {
        return new Rectangle();
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Now, you can use the factory to create shapes without knowing the exact type of shape being created:
public class DrawingApplication {
    public static void main(String[] args) {
        // Create a circle using the CircleFactory
        ShapeFactory circleFactory = new CircleFactory();
        Shape circle = circleFactory.createShape();
        circle.draw();

        // Create a rectangle using the RectangleFactory
        ShapeFactory rectangleFactory = new RectangleFactory();
        Shape rectangle = rectangleFactory.createShape();
        rectangle.draw();
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, we've used the Factory Method Pattern to create shapes without needing to know the specific implementation details of each shape. This separation of concerns allows you to add new shape types or modify existing ones without affecting the rest of your code, making it more maintainable and extensible.

The Factory Design Pattern is used extensively throughout the Java library itself, as well as in many Java libraries and frameworks. Here are a few common examples of how the Factory Pattern is used in the Java library:

  1. java.util.concurrent.Executors: The Executors class provides factory methods for creating different types of ExecutorService instances, such as newFixedThreadPool(), newCachedThreadPool(), and newSingleThreadExecutor(). These factory methods create instances of ExecutorService with specific configurations.

    ExecutorService executorService = Executors.newFixedThreadPool(4);
    
  2. java.util.Calendar: The Calendar class provides a method getInstance() that returns an instance of Calendar. This method is a factory method, and it allows you to create instances of the Calendar class without directly calling its constructor. The actual type of Calendar instance returned depends on the default locale and time zone.

    Calendar calendar = Calendar.getInstance();
    

In summary, the Factory Method Pattern in Java is a design pattern that encapsulates object creation by providing an interface for creating objects and allowing subclasses or concrete factories to implement the creation logic. It's a useful pattern for decoupling the client code from the concrete classes being created, promoting flexibility and maintainability in your software.

😍 If you enjoy the content, please 👍 like, 🔄 share, and 👣 follow for more updates!

Top comments (1)

Collapse
 
droar profile image
Damian Roa

A must-to-know pattern appart from the fixture or builder, very useful alongside dependency injection or even at times when testing.