DEV Community

Cover image for ๐Ÿš— Understanding the Factory Design Pattern ๐Ÿญ
Hossam Gouda
Hossam Gouda

Posted on โ€ข Edited on

๐Ÿš— Understanding the Factory Design Pattern ๐Ÿญ

Understanding the Factory Design Pattern

The Factory Design Pattern is a creational design pattern that provides an interface for creating objects in a superclass while allowing subclasses to alter the type of objects that will be created. This pattern is particularly useful when the exact types of objects to create are not known until runtime. It is applicable in various programming languages, including PHP, Java, C#, and Python.

When to Use the Factory Pattern

  • Complex Object Creation: When the creation process involves a lot of setup.
  • Decoupling: When you want to decouple the code that uses the objects from the code that creates them.
  • Managing Instantiation: When you want to manage and control the instantiation of objects.

Example in PHP

Letโ€™s create a simple example where we have different types of vehicles (Car and Truck) and a factory to create them.

Step 1: Create the Vehicle Interface

interface Vehicle {
    public function drive();
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create Concrete Classes

class Car implements Vehicle {
    public function drive() {
        return "Driving a car.";
    }
}

class Truck implements Vehicle {
    public function drive() {
        return "Driving a truck.";
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the VehicleFactory

class VehicleFactory {
    public static function createVehicle($type) {
        if ($type === 'car') {
            return new Car();
        } elseif ($type === 'truck') {
            return new Truck();
        }
        throw new Exception("Vehicle type not recognized.");
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Use the Factory

Now, let's use the factory to create vehicles:

try {
    $car = VehicleFactory::createVehicle('car');
    echo $car->drive(); // Output: Driving a car.

    $truck = VehicleFactory::createVehicle('truck');
    echo $truck->drive(); // Output: Driving a truck.
} catch (Exception $e) {
    echo $e->getMessage();
}
Enter fullscreen mode Exit fullscreen mode

Summary

In this example:

  • The Vehicle interface defines a contract for vehicle classes.
  • Car and Truck are concrete implementations of the Vehicle interface.
  • The VehicleFactory class has a static method for creating vehicles based on the given type.

This pattern allows you to encapsulate the instantiation logic and makes it easier to manage and extend your code. You can easily add new vehicle types without changing existing code in the factory, promoting adherence to the Open/Closed Principle.

Advantages of the Factory Pattern

  • Code Reusability: By centralizing object creation, you can reuse the factory methods across different parts of your application, reducing redundancy.

  • Ease of Maintenance: When changes are needed in the instantiation logic, you only have to update one place (the factory), rather than multiple locations where objects are created.

  • Improved Flexibility: You can add new types of vehicles (or other objects) easily without modifying existing code, which encourages clean architecture and design.

Disadvantages of the Factory Pattern

  • Complexity: Introduces an additional layer of abstraction, which may complicate the codebase for simple applications.

  • Overhead: Can lead to performance overhead due to the additional factory classes and methods.

Variations of the Factory Pattern

  • Abstract Factory Pattern: A higher-level factory that creates families of related or dependent objects without specifying their concrete classes.

  • Static Factory Method: Similar to the factory pattern but uses static methods for object creation.

Real-World Applications

The Factory Pattern is often utilized in popular frameworks and libraries. For instance, many dependency injection containers use factory methods to create instances dynamically based on configuration.

Comparison with Other Patterns

Comparing the Factory Pattern with other creational patterns can provide further insights into when to use each:

  • Singleton Pattern: Ensures a class has only one instance and provides a global point of access to it.
  • Builder Pattern: Focuses on the step-by-step construction of a complex object.

Unit Testing with Factory Pattern

The Factory Pattern can simplify unit testing by allowing mock objects to be easily created. This enables you to test code that depends on specific types without needing those types to be fully implemented.

Conclusion

Using design patterns like the Factory Pattern in software development is crucial for building scalable and maintainable applications. It provides a structured approach to object creation, leading to cleaner and more manageable code.

Image of Timescale

๐Ÿš€ pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applicationsโ€”without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more