2.2. Factory Method

Maheshmaddi
5 min readApr 9, 2023

--

The Factory Method pattern is a creational design pattern that provides an interface for creating objects in a superclass, while allowing subclasses to decide which class to instantiate. The pattern promotes loose coupling by deferring object instantiation to subclasses and enabling the creation of objects without exposing the exact class that will be instantiated.

The Factory Method pattern is particularly useful when:

  1. The exact type of the object to be created is determined at runtime.
  2. A class wants to delegate the responsibility of object creation to its subclasses.

To implement the Factory Method pattern, follow these steps:

  1. Define a common interface or an abstract class for the products.
  2. Create concrete product classes that implement the common interface or extend the abstract class.
  3. Declare a factory method in the creator class, which returns an object of the common interface or the abstract class.
  4. Implement the factory method in subclasses, returning an instance of the appropriate concrete product class.

Here’s a simple example of the Factory Method pattern in Java:

// Common interface for products
public interface Product {
void doSomething();
}

// Concrete product classes
public class ConcreteProductA implements Product {
@Override
public void doSomething() {
System.out.println("ConcreteProductA does something");
}
}

public class ConcreteProductB implements Product {
@Override
public void doSomething() {
System.out.println("ConcreteProductB does something");
}
}

// Creator class with factory method
public abstract class Creator {
public abstract Product factoryMethod();
}

// Concrete creator classes
public class ConcreteCreatorA extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}

public class ConcreteCreatorB extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}

In this example, the Product interface defines the common interface for all products, and ConcreteProductA and ConcreteProductB implement the interface. The Creator class declares the abstract factoryMethod(), which returns an object of type Product. The concrete creator classes, ConcreteCreatorA and ConcreteCreatorB, extend the Creator class and implement the factoryMethod(), returning instances of the corresponding concrete product classes.

Advantages of the Factory Method pattern:

  1. Loose coupling: The pattern decouples the client code from the concrete product classes, making it easier to add or modify product classes without affecting the client code.
  2. Extensibility: The Factory Method pattern allows for easy addition of new product types or modifications to existing product classes, as long as they conform to the common interface or abstract class.
  3. Encapsulation of object creation: The pattern encapsulates the object creation logic within the factory method, making it easier to maintain and modify.

Disadvantages of the Factory Method pattern:

  1. Increased complexity: The pattern introduces additional classes and interfaces, which can increase the overall complexity of the code.
  2. Dependency on subclasses: The Factory Method pattern relies on subclasses to implement the factory method, which can lead to a tighter coupling between the creator and concrete product classes.

When using the Factory Method pattern, carefully consider its benefits and drawbacks. Use the pattern when the exact type of the object to be created is determined at runtime, or when you want to delegate the responsibility of object creation to subclasses while maintaining a clean separation between the client code and the concrete product classes.

Use case: Creating Different Types of Cars with the Factory Method Pattern

Class diagram for different types of cars Factory Method pattern

A car manufacturer wants to create different types of cars such as sports cars, sedans, and SUVs. They want to ensure that their production process is efficient and scalable while also allowing for flexibility in creating different types of cars. To achieve this, they can implement the Factory Method pattern.

Solution: The car manufacturer can define an abstract Car class that provides the basic functionality required for all cars such as acceleration, braking, and steering. They can then create concrete subclasses such as SportsCar, Sedan, and SUV that implement the specific behavior and features for each type of car.

To create the different types of cars, the manufacturer can define a CarFactory interface that provides a createCar() method. Each concrete factory class such as SportsCarFactory, SedanFactory, and SUVFactory would implement the createCar() method and return the specific type of car instance.

This way, the car manufacturer can easily create new types of cars by simply adding new concrete factory classes without having to modify the existing code. The Factory Method pattern also allows for scalability by separating the creation of objects from their usage, making it easy to add new features or change the implementation without affecting the rest of the code.

Here’s an example Java code for the Factory Method pattern with the use case of creating different types of cars:

First, let’s define the abstract Car class:

public abstract class Car {
public abstract void accelerate();
public abstract void brake();
public abstract void steer();
}

Next, let’s define the concrete SportsCar, Sedan, and SUV classes:

public class SportsCar extends Car {
public void accelerate() {
// Implementation for sports car acceleration
}

public void brake() {
// Implementation for sports car braking
}

public void steer() {
// Implementation for sports car steering
}
}

public class Sedan extends Car {
public void accelerate() {
// Implementation for sedan acceleration
}

public void brake() {
// Implementation for sedan braking
}

public void steer() {
// Implementation for sedan steering
}
}

public class SUV extends Car {
public void accelerate() {
// Implementation for SUV acceleration
}

public void brake() {
// Implementation for SUV braking
}

public void steer() {
// Implementation for SUV steering
}
}

Next, let’s define the CarFactory interface

public interface CarFactory {
public Car createCar();
}

Now, let’s define the concrete factory classes SportsCarFactory, SedanFactory, and SUVFactory:

public class SportsCarFactory implements CarFactory {
public Car createCar() {
return new SportsCar();
}
}

public class SedanFactory implements CarFactory {
public Car createCar() {
return new Sedan();
}
}

public class SUVFactory implements CarFactory {
public Car createCar() {
return new SUV();
}
}

Finally, let’s use the CarFactory to create different types of cars:

CarFactory factory = new SedanFactory();
Car car = factory.createCar();
car.accelerate();
car. Brake();
car. Steer();

This code will create a Sedan car instance and call its accelerate(), brake(), and steer() methods. You can change the CarFactory instance to create different types of cars such as SportsCar or SUV by simply replacing SedanFactory with SportsCarFactory or SUVFactory.

Note: For complete list of design patterns click here

--

--