DEV Community

Saras Growth Space
Saras Growth Space

Posted on

LLD Object-Oriented Design: Factories & Object Creation (Managing Complexity of Creation)

After Dependency Injection, a natural question appears in real systems:

If classes don’t create objects, and dependencies are injected externally, who is responsible for creating them?

This is where Factories come in.


The Problem: Object Creation Becomes Complex

At first, object creation looks simple:

payment = CardPayment()
Enter fullscreen mode Exit fullscreen mode

But in real systems, creation logic becomes complex:

  • multiple implementations exist
  • selection depends on input or configuration
  • dependencies also need to be constructed

If this logic is scattered everywhere, the system becomes inconsistent.


Bad Design: Creation Inside Business Logic

class PaymentService:
    def process(self, type):
        if type == "card":
            payment = CardPayment()
        elif type == "upi":
            payment = UpiPayment()
Enter fullscreen mode Exit fullscreen mode

What’s wrong here?

  • creation logic is mixed with business logic
  • violates Open-Closed Principle
  • adding new types requires modifying existing code
  • duplication across services is likely

What is a Factory?

A factory is responsible for:

Centralizing and controlling object creation logic.

It hides complexity and returns ready-to-use objects.


Simple Factory Example

class PaymentFactory:
    def create(self, type):
        if type == "card":
            return CardPayment()
        elif type == "upi":
            return UpiPayment()
Enter fullscreen mode Exit fullscreen mode

Usage

payment = PaymentFactory().create("card")
payment.pay()
Enter fullscreen mode Exit fullscreen mode

What Changed?

  • object creation is centralized
  • business logic is clean
  • new implementations can be added in one place

Why Factories Matter

1. Centralized Creation Logic

All object creation rules live in one place.


2. Better Maintainability

Changes do not spread across the system.


3. Controlled Instantiation

Ensures correct object construction.


Factory vs Dependency Injection

These are often confused, but they solve different problems:

Dependency Injection Factory
provides objects creates objects
focuses on usage focuses on creation
reduces coupling centralizes instantiation

Real System Example

Notification System

class NotificationFactory:
    def create(self, type):
        if type == "email":
            return EmailNotifier()
        elif type == "sms":
            return SmsNotifier()
Enter fullscreen mode Exit fullscreen mode

Now services don’t care how objects are created:

notifier = factory.create("email")
notifier.send("Hello")
Enter fullscreen mode Exit fullscreen mode

Key Design Insight

Factories control object creation, ensuring consistency and isolating construction logic from business logic.


When to Use Factories

Use factories when:

  • multiple implementations exist
  • object creation involves logic or conditions
  • construction is complex or dependent on configuration

When NOT to Use Factories

Avoid factories when:

  • object creation is trivial
  • no variation exists
  • abstraction adds unnecessary complexity

Common Mistake

Beginners often:

  • put business logic inside factories
  • overuse factories for simple objects
  • confuse factory with dependency injection

Factories should only handle creation, nothing else.


Design Principle

Separate object creation from object usage to maintain clean and scalable architecture.


One-Line Takeaway

Factories centralize object creation logic, keeping business code clean and focused on behavior.

Top comments (0)