Skip to content

Factory Pattern - Abstract Object Creation

Updated: at 12:00 AM

1. The Problem

Problem: Object Creation Logic Is Scattered, Hard-coded, and Brittle

Systems often need to create objects belonging to a family of related types.
Example: creating different parsers (JSONParser, XMLParser, YAMLParser) depending on input.

Naive code:

if type == "json": return JSONParser()
elif type == "xml": return XMLParser()
elif type == "yaml": return YAMLParser()

Issues:

We need a way to centralize and abstract creation, keeping client code unaware of concrete implementations.

2. Unified Concept: The Factory Pattern

Factory = decouple what you create from how you create it.

There are two levels of abstraction:

2.1 Simple Factory (not a GoF pattern, but widely used)

Use it when:

2.2 Factory Method (GoF pattern)

Use it when:

Unification Mental Model:

3. Implementation: Simple Factory + Factory Method in One Flow

3.1 Product interface

from abc import ABC, abstractmethod

class Parser(ABC):
    @abstractmethod
    def parse(self, data: str) -> dict:
        pass

3.2 Concrete products

class JSONParser(Parser):
    def parse(self, data: str) -> dict:
        return {"json": data}

class XMLParser(Parser):
    def parse(self, data: str) -> dict:
        return {"xml": data}

3A. Simple Factory Implementation

A single class that decides which product to create.

class ParserFactory:
    @staticmethod
    def create_parser(type_: str) -> Parser:
        if type_ == "json":
            return JSONParser()
        if type_ == "xml":
            return XMLParser()
        raise ValueError("Unknown parser type")

Usage:

parser = ParserFactory.create_parser("json")

Advantages:

Limitations:

3B. Factory Method Implementation (GoF)

Context class holds a template method that relies on a factory method.

class ParserApp(ABC):
    @abstractmethod
    def create_parser(self) -> Parser:
        pass

    def run(self, data: str):
        parser = self.create_parser()
        return parser.parse(data)

Concrete creators:

class JSONParserApp(ParserApp):
    def create_parser(self) -> Parser:
        return JSONParser()

class XMLParserApp(ParserApp):
    def create_parser(self) -> Parser:
        return XMLParser()

Usage:

app = JSONParserApp()
result = app.run("data")

Advantages:

4. When to Use Simple Factory vs Factory Method

Use Simple Factory when:

Use Factory Method when:

Mental shortcut:

5. Common Pitfalls