This is a creational pattern, the factory method pattern is a design pattern that allows for the creation of objects without specifying the type of object that is to be created in code. A factory class contains a method that allows determination of the created type at run-time.
The factory pattern is used to replace class constructors, abstracting the process of object generation so that the type of the object instantiated can be determined at run-time.
Elements involved:
- FactoryBase: This is an abstract base class for the concrete factory classes that will actually generate new objects.
- ConcreteFactory: Inheriting from the FactoryBase class, the concrete factory classes inherit the actual factory method. This is overridden with the object generation code unless already implemented in full in the base class.
- ProductBase: This abstract class is the base class for the types of object that the factory can create. It is also the return type for the factory method.
- ConcreteProduct: Multiple subclasses of the Product class are defined, each containing specific functionality. Objects of these classes are generated by the factory method.
We should use the Factory Method design pattern when:
- when a class can’t anticipate the type of the objects it is supposed to create.
- when a class wants its subclasses to be the ones to specific the type of a newly created object.
Let´s see some code:
public abstract class FactoryBase {
public abstract ProductBase build(int type);
}
public abstract class ProductBase {
public abstract void whoIAm();
}
public class ConcreteFactory extends FactoryBase {
@Override
public ProductBase build(int type) {
final ProductBase productBase;
switch (type) {
case 1:
productBase = new ConcreteProduct1();
break;
case 2:
productBase = new ConcreteProduct2();
break;
default:
throw new IllegalArgumentException(String.format("Illegal type %s", type));
}
return productBase;
}
}
public class ConcreteProduct1 extends ProductBase {
@Override
public void whoIAm() {
System.out.println("I am ConcreteProduct1");
}
}
public class ConcreteProduct2 extends ProductBase {
@Override
public void whoIAm() {
System.out.println("I am ConcreteProduct2");
}
}
public class Main {
public static void main(String[] args) {
final FactoryBase factoryBase = new ConcreteFactory();
factoryBase.build(1).whoIAm();
factoryBase.build(2).whoIAm();
}
}
The output after the execution should be something like that:
I am ConcreteProduct1
I am ConcreteProduct2
You can find the code in my GitHub repository “design-apperns“.