Creational Factory Design Patterns: Simple, Method, and Abstract

Classifications of Factory Patterns

  • Simple Factory
  • Factory Method
  • Abstract Factory

Pattern Details and Implementations

Simple Factory

A Simple Factory encapsulates object creation within a single class. Clients rely on a parameter passed to the factory to determine which concrete product subclass to instantiate, while interacting with the product through a shared interface.

Structural Components

ComponentRelationshipResponsibility
Abstract ProductParent of Concrete ProductsDeclares the common interface for objects created by the factory
Concrete ProductSubclass of Abstract ProductProvides the specific implementation of the product
FactoryInvoked by the clientReturns a specific product instance based on input parameters

Implementation Scenario

Consider a logistics system where goods can be transported by road or sea. A central dispatch factory can determine the appropriate vehicle based on the requested mode.

public class TransportCreator {
    public static Transport arrangeDelivery(String mode) {
        if ("ROAD".equalsIgnoreCase(mode)) {
            return new Truck();
        } else if ("SEA".equalsIgnoreCase(mode)) {
            return new Ship();
        }
        throw new IllegalArgumentException("Unsupported transport mode: " + mode);
    }
}

public interface Transport {
    void deliver();
}

public class Truck implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering cargo by road.");
    }
}

public class Ship implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering cargo by sea.");
    }
}

// Client execution
public class DispatchSystem {
    public static void main(String[] args) {
        Transport roadTransport = TransportCreator.arrangeDelivery("ROAD");
        roadTransport.deliver();
        Transport seaTransport = TransportCreator.arrangeDelivery("SEA");
        seaTransport.deliver();
    }
}

Output:

Delivering cargo by road.
Delivering cargo by sea.

Factory Method

The Factory Method pattern defines an interface for creating objects but allows subclasses to alter the type of objects that will be created. It addresses the Open-Closed Principle violation in Simple Factory by deferring instantiation to concrete creator classes.

Structural Components

ComponentRelationshipResponsibility
Abstract ProductParent of Concrete ProductsDeclares the common interface for objects created
Concrete ProductSubclass of Abstract ProductProvides the specific implementation of the product
Abstract CreatorParent of Concrete CreatorsDeclares the factory method returning a product type
Concrete CreatorSubclass of Abstract CreatorImplements the factory method to return a specific product instance

Implementation Scenario

If the logistics system needs to support air transport, modifying the existing dispatch class would violate the Open-Closed Principle. Instead, separate logistics subclasses define the vehicle instantiation.

public abstract class LogisticsOrganizer {
    public abstract Transport createTransport();
}

public class RoadLogistics extends LogisticsOrganizer {
    @Override
    public Transport createTransport() {
        return new Truck();
    }
}

public class SeaLogistics extends LogisticsOrganizer {
    @Override
    public Transport createTransport() {
        return new Ship();
    }
}

public class AirLogistics extends LogisticsOrganizer {
    @Override
    public Transport createTransport() {
        return new Airplane();
    }
}

public interface Transport {
    void deliver();
}

public class Truck implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering cargo by road.");
    }
}

public class Ship implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering cargo by sea.");
    }
}

public class Airplane implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering cargo by air.");
    }
}

// Client execution
public class DispatchSystem {
    public static void main(String[] args) {
        LogisticsOrganizer seaLogistics = new SeaLogistics();
        Transport seaTransport = seaLogistics.createTransport();
        seaTransport.deliver();

        LogisticsOrganizer airLogistics = new AirLogistics();
        Transport airTransport = airLogistics.createTransport();
        airTransport.deliver();
    }
}

Output:

Delivering cargo by sea.
Delivering cargo by air.

Abstract Factory

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. Each concrete factory corresponds to a specific product family.

Structural Components

ComponentRelationshipResponsibility
Abstract ProductParent of Concrete ProductsDeclares the common interface for a product type
Concrete ProductSubclass of Abstract ProductProvides the specific implementation of the product
Abstract FactoryParent of Concrete FactoriesDeclares creation methods for each abstract product type
Concrete FactorySubclass of Abstract FactoryImplements creation methods to return specific family product instances

Implementation Scenario

Expanding the logistics system, cargo requires not only a vehicle but also appropriate packaging. Road logistics use trucks and wooden crates, while sea logistics use ships and steel containers. An abstract factory can manage these product families cohesively.

public interface LogisticsFactory {
    Transport createTransport();
    Packaging createPackaging();
}

public class RoadLogisticsFactory implements LogisticsFactory {
    @Override
    public Transport createTransport() {
        return new Truck();
    }

    @Override
    public Packaging createPackaging() {
        return new WoodenCrate();
    }
}

public class SeaLogisticsFactory implements LogisticsFactory {
    @Override
    public Transport createTransport() {
        return new Ship();
    }

    @Override
    public Packaging createPackaging() {
        return new SteelContainer();
    }
}

public interface Transport {
    void deliver();
}

public interface Packaging {
    void pack();
}

public class Truck implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering by road.");
    }
}

public class Ship implements Transport {
    @Override
    public void deliver() {
        System.out.println("Delivering by sea.");
    }
}

public class WoodenCrate implements Packaging {
    @Override
    public void pack() {
        System.out.println("Packing in a wooden crate.");
    }
}

public class SteelContainer implements Packaging {
    @Override
    public void pack() {
        System.out.println("Packing in a steel container.");
    }
}

// Client execution
public class DispatchSystem {
    public static void main(String[] args) {
        LogisticsFactory roadFactory = new RoadLogisticsFactory();
        Transport roadTransport = roadFactory.createTransport();
        Packaging roadPackaging = roadFactory.createPackaging();
        roadTransport.deliver();
        roadPackaging.pack();

        LogisticsFactory seaFactory = new SeaLogisticsFactory();
        Transport seaTransport = seaFactory.createTransport();
        Packaging seaPackaging = seaFactory.createPackaging();
        seaTransport.deliver();
        seaPackaging.pack();
    }
}

Output:

Delivering by road.
Packing in a wooden crate.
Delivering by sea.
Packing in a steel container.

Tags: Design Patterns Factory Pattern Simple Factory Factory Method Abstract Factory

Posted on Wed, 27 May 2026 17:37:02 +0000 by jamz310