Decoupling Creation: Implementing the Factory Pattern in Python
Overview of the Factory Pattern
In complex software systems, hardcoding object creation leads to rigid, fragile code. The Factory Pattern solves this by separating the process of object creation from the code that uses those objects. This separation is vital for maintaining high cohesion and low coupling. By shifting the responsibility of instantiation to a specialized factory, the main application logic remains agnostic to specific implementation details. If you need to swap a low-quality video codec for a high-quality one, you only change the factory, not the entire workflow.
Prerequisites
To follow this guide, you should possess a solid understanding of Python fundamentals, specifically Object-Oriented Programming (OOP). Familiarity with Abstract Base Classes (ABCs) and the concept of Inheritance is required. You should also understand basic software design principles like Cohesion and Coupling.

Key Libraries & Tools
- abc: The built-in Python module for defining Abstract Base Classes.
- pathlib: Used for object-oriented filesystem path manipulation.
Code Walkthrough
First, we define an abstract interface using the abc module. This ensures every factory provides the necessary creation methods.
from abc import ABC, abstractmethod
class ExporterFactory(ABC):
@abstractmethod
def get_video_exporter(self) -> VideoExporter:
"""Returns a new video exporter instance."""
@abstractmethod
def get_audio_exporter(self) -> AudioExporter:
"""Returns a new audio exporter instance."""
Next, we implement concrete factories. Each factory represents a specific configuration, such as a "Fast" or "Master" quality setup.
class FastExporter(ExporterFactory):
def get_video_exporter(self) -> VideoExporter:
return H264BaselineVideoExporter()
def get_audio_exporter(self) -> AudioExporter:
return AACAudioExporter()
Finally, we use Dependency Injection by passing the factory into the main function. This removes the need for the main() function to know about specific exporter classes.
def main(factory: ExporterFactory):
video_exporter = factory.get_video_exporter()
audio_exporter = factory.get_audio_exporter()
# Proceed with export logic...
Syntax Notes
We use Type Hinting to specify that the main function expects an ExporterFactory type. This increases code readability and assists IDEs in providing better autocomplete. The use of the @abstractmethod decorator enforces that any subclass must implement the defined methods, preventing runtime errors caused by missing functionality.
Practical Examples
Factories shine in scenarios where objects must be grouped by environment or locale. Consider a Global Web Shop: a UKFactory might return a GBP currency object and a VAT tax calculator, while a USFactory returns USD and SalesTax objects. The checkout logic remains identical; only the factory changes.
Tips & Gotchas
Avoid the "Class Explosion" trap. If your application requires every possible combination of video and audio codecs (e.g., Low Video + High Audio), creating a factory for every permutation is inefficient. In those cases, favor Composition and Dependency Inversion over the static Factory Pattern to maintain flexibility without cluttering your codebase with dozens of subclasses.
- Abstract Factory
- 25%· products
- Arjan
- 25%· people
- Factory Pattern
- 25%· products
- Python
- 25%· products

The Factory Pattern in Python // Separate Creation From Use
WatchArjanCodes // 14:58
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!