Factory vs Abstract Factory Pattern: Key Differences and Usage
Factory Pattern creates objects of a single product type through a common interface, while the Abstract Factory Pattern creates families of related or dependent objects without specifying their concrete classes. Essentially, Factory focuses on one product, Abstract Factory handles multiple related products.Quick Comparison
This table summarizes the main differences between Factory and Abstract Factory patterns.
| Factor | Factory Pattern | Abstract Factory Pattern |
|---|---|---|
| Purpose | Creates one product type | Creates families of related products |
| Number of Products | Single product | Multiple related products |
| Interface | One factory interface | Multiple factory methods grouped |
| Complexity | Simpler | More complex |
| Use Case | When only one product type is needed | When multiple related products are needed |
| Example | VehicleFactory creates Cars | VehicleFactory creates Cars and Bikes |
Key Differences
The Factory Pattern provides a way to create objects without exposing the creation logic to the client, focusing on a single product type. It defines a method for creating objects but lets subclasses decide which class to instantiate.
In contrast, the Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It groups multiple factory methods to create different but related products, ensuring that products from the same family are used together.
While Factory is simpler and suitable for single product creation, Abstract Factory is more powerful for complex systems requiring multiple related products to be created consistently.
Code Comparison
interface Vehicle { void drive(); } class Car implements Vehicle { public void drive() { System.out.println("Driving a car"); } } class Bike implements Vehicle { public void drive() { System.out.println("Riding a bike"); } } class VehicleFactory { public static Vehicle getVehicle(String type) { if (type.equalsIgnoreCase("car")) { return new Car(); } else if (type.equalsIgnoreCase("bike")) { return new Bike(); } throw new IllegalArgumentException("Unknown vehicle type"); } } public class FactoryDemo { public static void main(String[] args) { Vehicle vehicle = VehicleFactory.getVehicle("car"); vehicle.drive(); } }
Abstract Factory Equivalent
interface Car { void drive(); } interface Bike { void ride(); } class SportsCar implements Car { public void drive() { System.out.println("Driving a sports car"); } } class SportsBike implements Bike { public void ride() { System.out.println("Riding a sports bike"); } } interface VehicleFactory { Car createCar(); Bike createBike(); } class SportsVehicleFactory implements VehicleFactory { public Car createCar() { return new SportsCar(); } public Bike createBike() { return new SportsBike(); } } public class AbstractFactoryDemo { public static void main(String[] args) { VehicleFactory factory = new SportsVehicleFactory(); Car car = factory.createCar(); Bike bike = factory.createBike(); car.drive(); bike.ride(); } }
When to Use Which
Choose Factory Pattern when you need to create objects of a single product type and want to hide the creation logic from the client. It is ideal for simple scenarios where only one kind of product is involved.
Choose Abstract Factory Pattern when your system requires creating families of related products that must be used together. It ensures consistency among products and is suitable for complex systems with multiple product variants.