javadesign-patterns

Why is object creation have separate interdace in Factory Method Design Pattern?


I am studying design patterns and in an implementation in Java, I came across an example. My main doubt is why do we have to create a separate interface for object creation of the subclasses. Why can't we create just create instance using the new keyword for the child class?

public interface Shape {
    void draw();
}

public class Square implements Shape {
    public void draw() {
        System.out.println("Drawing a Square");
    }
}

public class Circle implements Shape {
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}

public interface ShapeFactory {
    Shape createShape();
}

public class SquareFactory implements ShapeFactory {
    public Shape createShape() {
        return new Square();
    }
}

public class CircleFactory implements ShapeFactory {
    public Shape createShape() {
        return new Circle();
    }
}

public class Main {

    public static void main(String[] args) {
        ShapeFactory squareFactory = new SquareFactory();
        Shape square = squareFactory.createShape();
        square.draw();

        ShapeFactory circleFactory = new CircleFactory();
        Shape circle = circleFactory.createShape();
        circle.draw();
    }
}

Why cannot I just do:

public class Main {
    
    public static void main(String[] args) {
        
        Shape square = new Square();

        Shape circle = new Circle();
    }
}

Solution

  • Why can't we create just create instance using the new keyword for the child class?

    The calling code can indeed create instances of the child classes directly, provided that it has knowledge of, and access to, those child classes to begin with. While this is the case in the simple example in your question, this is not necessarily always the case. Let's say the person who implemented the calling code was particularly bad at geometry, then you'd be stuck with just circles and squares forever.

    Using the factory method pattern, all the calling code needs to do is accept a factory that creates some kind of Shape. If, as a user, you decide that you want to create hexagons, you can do that just by creating a Hexagon class and passing a HexagonFactory instance to the calling code, without having to make changes to the calling code itself.

    In essence, this is a decoupling technique, and allows you to design software that adheres more closely to the SOLID principles.