Java – Why use the factory method pattern instead of a simple factory

Why use the factory method pattern instead of a simple factory… here is a solution to the problem.

Why use the factory method pattern instead of a simple factory

Compared to a simple factory, I’m trying to understand when to use the factory method pattern, and I know how each method is implemented, but I don’t fully understand what it means.

Let’s say I have a client that provides a string (car name), and based on that string, the factory provides the object.

I

know that the method factory meets the open/closed principle, and if I have a new car brand, such as Mercedes, I will have to edit the switch case and add new ones, which would be bad practice. But after using the factory method, my factory can’t decide which object to make because there is no switch box. I think I’m missing a little bit here. If I have a different logic/strategy when creating the car object, maybe I should use the factory method, one can generate a random car object, and the other can get a string and generate an object based on that string.

If I use the getCar() function in a factory method and do some more logic there, like car.tuneEngine() etc, is that also a good practice before returning an object ready to use?

Simple factory

public class FordCar extends Car {

public FordCar() {
        super("Ford", "Mondeo", 1.6);
         TODO Auto-generated constructor stub
    }

@Override
    public void move() {
        System.out.println("Ford moves");

}

}

public class CarFactory {

public Car getCar(String brand) {
        switch (brand) {
        case "ferrari":
            return new FerrariCar();
        case "ford":
            return new FordCar();
        default:
            return null;

}
    }
}

public class Client {

public static void main(String[] args) {

Simple factory
        CarFactory carFactory = new CarFactory();
        Car clientSimpleCar = carFactory.getCar("ford");
        clientSimpleCar.move();     
    }
}

Factory method pattern

public abstract class CarMethodFactory {

public Car getCar(){
        Car car = createCar();
        return car;
    }

public abstract Car createCar();

}

public class FordMethodFactory extends CarMethodFactory{

@Override
    public Car createCar() {
        return new FordCar();
    }

}

public class Client {

public static void main(String[] args) {

CarMethodFactory carMethodFactory = new FordMethodFactory();
        Car clientMethodCar = carMethodFactory.getCar();
        clientMethodCar.move();

}

}

Solution

It may make sense to keep the GoF definitions of factory methods and abstract factories for learning purposes. GoF is a common ground reference and discussion around basic patterns. It’s best to be wary of the many “examples” found on several ad-filled websites, as some are misleading at best.

Stick to GoF has 2 factory modes: Factory Method and Abstract Factory.

The simple factory is not a separate pattern, it is a special case of the factory approach. There is no mention of the simple factory pattern as a naming pattern in GOF. See below.

Factory Method: This does not involve factory objects. As the name suggests, it involves factory methods().

Example: Consider a TextEditor base class that contains subclasses such as C#, PHP, JS, HTML, and so on. Each subclass needs its own SyntaxChecker object. The TextEditor base class has an abstract CreateSyntaxChecker() method, and each subclass of the TextEditor implements the CreateSyntaxChecker() interface and returns the specific SyntaxChecker required by the subclass. Consider the following typical use of pseudocode.

Editor = new PHPTextEditor;   instantiates PHP subclass of  TextEditor
_syntaxChecker = this->CreateSyntaxChecker();      The constructor of  
PHPTextEditor invokes its over-ridden CreateSyntaxChecker() method, which returns 
the correct PHP SyntaxChecker object.

This is in line with the intent of the GoF factory approach. “Define the interface used to create the object, but let the subclass decide which class to instantiate.”

“Simple factory”: is a variant of the factory method. In this variant, using the text editor example, the TextEditor base class has a concrete (rather than abstract) method, CreateSyntaxChecker(), which may or may not be overridden in the subclass, and if not, the base class implementation is used.

Abstract Factory: The GoF intent of the abstract factory is to “provide an interface to create a family of related or dependent objects without specifying their concrete classes.” This in practice means creating an abstract factory class whose subclasses define how to create related object families.

Example: Extending the TextEditor example, we realized that we needed language-specific Formatter and Debug modules in addition to SyntaxChecker. (We can achieve this by applying the Factory Method multiple times, but this involves editing multiple classes). Define an abstract factory class with 3 abstract methods CreateSyntaxChecker(), CreateDebugger(), CreateFormatter(). Then define subclasses PHPFactory, JSFactory, HTMLFactory, etc., each providing an implementation of 3 methods and returning the correct object instance.

Consider the following typical use of pseudocode.

Factory = new PHPFactory();
Editor = new PHPEditor(Factory);     Constructor of PHPEditor will invoke the 3 
Factory methods to instantiate the correct versions of the SyntaxChecker, Debugger 
and Formatter objects.

I highly recommend refactoring your code to conform to the GoF “standard” as a starting point, especially when learning. Later, when you are sure of what you are doing, feel free to tweak and adjust to suit your needs :-).

Related Problems and Solutions