1. Definition

The Factory Method Design Pattern provides an interface for creating instances of a class, with its subclasses deciding which class to instantiate. This encapsulates object creation and promotes flexibility.

2. Problem Statement

Consider building a drawing tool where you need to create polygons based on the number of sides. However, creating polygons directly from the client can be error-prone and lacks central control. How can you efficiently and flexibly create different polygon objects without exposing the creation logic to the client?

3. Solution

The solution lies in the Factory Method pattern: Create a centralized PolygonFactory to produce instances of Polygon interface based on the given number of sides. This abstracts away the direct instantiation of concrete polygon classes from the client.

4. Real-World Use Cases

1. Graphics editors creating different shapes based on user input.

2. Games rendering different entities based on configurations or player choices.

3. CAD software constructing different geometric entities based on design requirements.

5. Implementation Steps

1. Define the Polygon interface.

2. Implement concrete classes for different polygons (e.g., Triangle, Square, Pentagon, Octagon).

3. Create a PolygonFactory to produce instances of Polygon based on the given number of sides.

4. Implement the client code to use the factory for creating polygons.

6. Implementation

// Polygon interface
public interface Polygon {
    public String getType();
}

// Concrete Polygon implementations
public class Triangle implements Polygon {
    @Override
    public String getType() {
        return "Triangle";
    }
}

public class Square implements Polygon {
    @Override
    public String getType() {
        return "Square";
    }
}

public class Pentagon implements Polygon {
    @Override
    public String getType() {
        return "Pentagon";
    }
}

public class Octagon implements Polygon {
    @Override
    public String getType() {
        return "Octagon";
    }
}

// PolygonFactory
public class PolygonFactory {
    public static Polygon getInstance(int sides) {
        switch (sides) {
            case 3: return new Triangle();
            case 4: return new Square();
            case 5: return new Pentagon();
            case 8: return new Octagon();
            default: throw new IllegalArgumentException("No such polygon.");
        }
    }
}

// Client
public class Client {
    public static void main(String[] args) {
        System.out.println(PolygonFactory.getInstance(3).getType());
        System.out.println(PolygonFactory.getInstance(4).getType());
        System.out.println(PolygonFactory.getInstance(5).getType());
        System.out.println(PolygonFactory.getInstance(8).getType());
    }
}

Output:

Triangle
Square
Pentagon
Octagon

Explanation:

The Factory Method design pattern in the example decouples the client code (Client class) from the concrete polygon implementations. Instead of instantiating polygons directly, the client uses the PolygonFactory to obtain the needed polygons. This design promotes flexibility and allows for easy extension (e.g., adding more polygon types) without modifying client code.

7. When to use?

The Factory Method pattern is beneficial when:

1. A class can’t anticipate the type of objects it should create.

2. Classes delegate responsibilities to their subclasses to specify which objects to create.

3. The object creation process is complex or involves business logic, and you want to centralize this process.