Fundamentals 7 min read

Understanding the Object Factory Design Pattern with Python Examples

Object Factory is a design pattern that centralizes object creation, enhancing decoupling, extensibility, and management of instances, and this article explains its principles, benefits, and provides five Python code examples illustrating various scenarios such as type-based creation, configuration-driven instantiation, logging factories, singleton factories, and object caching.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Understanding the Object Factory Design Pattern with Python Examples

Object Factory (Object Factory) is a design pattern used to create and manage the instantiation process of objects. It offers a flexible way to create objects, making code more extensible and maintainable.

In the Object Factory pattern, a factory class is responsible for instantiating objects and returning appropriate object instances to the caller, so the caller does not need to depend directly on concrete object classes.

Benefits of using the Object Factory pattern include:

Decoupling : Callers obtain objects through the factory, reducing code coupling.

Extensibility : Adding new product classes only requires updating the factory, not the caller code.

Managed instantiation : The factory can handle creation, caching, and reuse of objects.

Complex scenarios such as conditional creation or configuration‑driven creation are also supported.

The article presents five illustrative Python examples.

Example 1: Creating different types of product objects

class Product:
    def __init__(self, name):
        self.name = name
    def get_name(self):
        return self.name

class ProductFactory:
    @staticmethod
    def create_product(product_type, name):
        if product_type == "A":
            return ProductA(name)
        elif product_type == "B":
            return ProductB(name)
        else:
            raise ValueError("Invalid product type")

class ProductA(Product):
    def __init__(self, name):
        super().__init__(name)

class ProductB(Product):
    def __init__(self, name):
        super().__init__(name)

# Using the object factory to create different product objects
product_factory = ProductFactory()
product_a = product_factory.create_product("A", "Apple")
product_b = product_factory.create_product("B", "Banana")

Example 2: Dynamically creating objects based on a configuration file

import json

class Product:
    def __init__(self, name):
        self.name = name
    def get_name(self):
        return self.name

class ProductFactory:
    def __init__(self, config_file):
        self.config = self.load_config(config_file)
    @staticmethod
    def load_config(config_file):
        with open(config_file, 'r') as f:
            return json.load(f)
    def create_product(self, name):
        product_type = self.config.get("product_type", "default")
        if product_type == "A":
            return ProductA(name)
        elif product_type == "B":
            return ProductB(name)
        else:
            return Product(name)

class ProductA(Product):
    def __init__(self, name):
        super().__init__(name)

class ProductB(Product):
    def __init__(self, name):
        super().__init__(name)

# Using the object factory to create a product based on configuration
product_factory = ProductFactory("config.json")
product = product_factory.create_product("Apple")

Example 3: Factory method pattern for creating different logger objects

import logging

class Logger:
    def log(self, message):
        pass

class FileLogger(Logger):
    def log(self, message):
        # Implement file‑writing logic
        pass

class DatabaseLogger(Logger):
    def log(self, message):
        # Implement database‑writing logic
        pass

class LoggerFactory:
    @staticmethod
    def create_logger(logger_type):
        if logger_type == "file":
            return FileLogger()
        elif logger_type == "database":
            return DatabaseLogger()
        else:
            raise ValueError("Invalid logger type")

# Using the factory method to create a logger
logger_factory = LoggerFactory()
logger = logger_factory.create_logger("file")
logger.log("Log message")

Example 4: Factory for creating a singleton object

class Singleton:
    def __init__(self):
        pass

class SingletonFactory:
    instance = None
    @classmethod
    def get_instance(cls):
        if cls.instance is None:
            cls.instance = Singleton()
        return cls.instance

# Getting the singleton instance via the factory
singleton = SingletonFactory.get_instance()

Example 5: Factory that caches created objects

class Product:
    def __init__(self, name):
        self.name = name

class ProductFactory:
    _product_cache = {}
    @staticmethod
    def create_product(name):
        if name in ProductFactory._product_cache:
            return ProductFactory._product_cache[name]
        else:
            product = Product(name)
            ProductFactory._product_cache[name] = product
            return product

# Using the factory with caching
product_factory = ProductFactory()
product_a = product_factory.create_product("A")
product_b = product_factory.create_product("B")
product_a_cached = product_factory.create_product("A")  # Retrieved from cache

These examples demonstrate how the Object Factory pattern can be applied in various contexts, from simple type‑based creation to configuration‑driven instantiation, logger factories, singleton factories, and object caching, allowing developers to design flexible and maintainable object creation mechanisms.

PythoncachingDesign PatternsingletonFactory MethodObject Factory
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.