Factory Pattern: Your Object Assembly Line
By Misbahul Munir3 min read613 words

Factory Pattern: Your Object Assembly Line

Backend Development
design pattern
creational pattern

In our previous post, we explored the Singleton Pattern—a way to ensure a single instance of a class. Today, let’s dive into another classic and practical design pattern: the Factory Pattern.

The Factory Pattern is particularly useful in backend systems that deal with complex object creation—especially when you don’t want to tightly couple your code to specific classes. Let’s see how it works.


What Is the Factory Pattern?

The Factory Pattern is a creational design pattern that abstracts the process of object creation. Instead of instantiating objects directly using the

new
keyword (or
ClassName()
in Python), you delegate the task of creating the object to a separate factory function or class.

This allows the code to be flexible, decoupled, and easier to extend when new types are introduced.


Real-World Analogy: A Restaurant Kitchen

Imagine you go to a restaurant and order food. You don’t go into the kitchen and cook it yourself. Instead, you place your order, and the kitchen (factory) prepares and delivers the dish you asked for.

You don’t care how the dish is made—you just care that you get the right meal.

Likewise, in the Factory Pattern, you request an object by type or configuration, and the factory returns a ready-to-use instance—without exposing the complex creation logic.


Real Backend Example: Message Queue Factory in Python

Suppose you’re building a microservices backend system that needs to publish messages to different message queues (e.g., RabbitMQ, Kafka, AWS SQS). You want to hide the setup logic behind a single interface, so your code can easily switch or extend to new queues.

Step 1: Define a Common Interface

from abc import ABC, abstractmethod class MessageQueue(ABC): @abstractmethod def send(self, message: str): pass

Step 2: Implement Concrete Queue Classes

class RabbitMQQueue(MessageQueue): def send(self, message: str): print(f"Sending to RabbitMQ: {message}") class KafkaQueue(MessageQueue): def send(self, message: str): print(f"Sending to Kafka: {message}") class SQSQueue(MessageQueue): def send(self, message: str): print(f"Sending to AWS SQS: {message}")

Step 3: Create the Factory

class MessageQueueFactory: @staticmethod def get_queue(queue_type: str) -> MessageQueue: if queue_type == "rabbitmq": return RabbitMQQueue() elif queue_type == "kafka": return KafkaQueue() elif queue_type == "sqs": return SQSQueue() else: raise ValueError(f"Unsupported queue type: {queue_type}")

Usage

# main.py queue_type = "kafka" # could be loaded from config/env queue = MessageQueueFactory.get_queue(queue_type) queue.send("Hello, microservices!")

Now your app can switch between message queue systems without touching the business logic.


Where Factory Pattern Shines in Backend Systems

  • Switching between databases (e.g., PostgreSQL vs. MongoDB)
  • Choosing serialization strategies (e.g., JSON vs. Protobuf)
  • Handling authentication providers (e.g., OAuth, JWT, API Key)
  • Creating service clients (e.g., Stripe vs. PayPal gateways)
  • Processing different file formats (e.g., CSV, JSON, XML)

Gotchas

  • Don’t over-engineer. If you only have one type and don’t plan on extending, a factory might be unnecessary.
  • Factories can hide dependencies—make sure to document or design clean interfaces for better maintainability.
  • Factories can also grow messy if overloaded with too many
    if
    conditions—consider using a registry-based factory or dependency injection for more extensibility.

Final Thoughts

The Factory Pattern is a clean and scalable way to decouple object creation from your application logic. Whether you're dealing with message queues, payment gateways, or file parsers, factories help you plug-and-play new implementations without rewriting the core code.

Use it when you need flexibility in choosing implementations—but avoid unnecessary abstraction if your use case is simple.


Next in this design pattern series: the Strategy Pattern — an elegant way to switch between algorithms or behaviors dynamically. Follow along!