The Factory Method pattern is one of the most commonly used design patterns in object-oriented programming. It falls under the category of creational patterns, as it deals with creating objects. The primary goal of the Factory Method pattern is to provide an interface for creating objects, but it leaves the actual instantiation logic to its sub-classes, thereby promoting loose coupling and increased flexibility.
The pattern consists of a Creator, a Product interface, and Concrete Products that implement the Product interface. The Creator class is the one that has the Factory Method, which is responsible for creating objects of the Concrete Products. The Concrete Products are the various objects that we want to create.
Here is an example of the Factory Method pattern in Java:
interface Car { // Product interface
void drive();
}
class Sedan implements Car { // Concrete Product
public void drive() {
System.out.println("Driving a sedan");
}
}
class SUV implements Car { // Another Concrete Product
public void drive() {
System.out.println("Driving an SUV");
}
}
abstract class CarFactory { // Creator
abstract Car createCar();
}
class SedanFactory extends CarFactory { // Concrete Creator
Car createCar() {
return new Sedan();
}
}
class SUVFactory extends CarFactory { // Another Concrete Creator
Car createCar() {
return new SUV();
}
}
public class Main {
public static void main(String[] args) {
CarFactory factory = new SedanFactory(); // Creator can be switched out for another Concrete Creator at runtime
Car car = factory.createCar(); // Driver code does not depend on Concrete Products, only on creator interface
car.drive(); // Outputs "Driving a sedan"
}
}
In this example, we have the Product interface ‘Car‘, and two Concrete Products, ‘Sedan‘ and ‘SUV‘. We also have the Creator abstract class ‘CarFactory‘, which has the Factory Method ‘createCar()‘. The two Concrete Creators, ‘SedanFactory‘ and ‘SUVFactory‘, inherit from the ‘CarFactory‘ class and implement their own respective ‘createCar()‘ methods, which return instances of their respective Concrete Products.
The Driver code ‘Main‘ creates an instance of ‘SedanFactory‘ as a Creator, but at runtime, it can be switched out for any other Concrete Creator without affecting the logic of ‘Main‘. We then call the ‘createCar()‘ method on the factory, which returns an instance of a Concrete Product, which we can use without knowing which specific Product was instantiated. Finally, we call the ‘drive()‘ method, which outputs either "Driving a sedan" or "Driving an SUV", depending on which Concrete Product was created.