Full analysis of Python design patterns
Friends who have just jumped from static languages to Python, do you think as soon as you look at the design pattern: "How can the code size be reduced by half and still be able to do fancy things?"
Design patterns are general solutions to common problems in software design. In Python, we take advantage of its dynamic nature to implement these patterns in simpler code than in Java. 👉 Complete Python design pattern code set: faif/python-patterns
This article will cover the most commonly used and Pythonic modes among the three categories: Creative, Structural, and Behavioral. Each mode is equipped with a minimalist code example so that you can get started after reading it.
1. Creational Patterns
Core Goal: Completely decouple these three things from the business logic of the system: "Who creates the object", "How to create it", and "What does it represent" - so that when the implementation is changed, the caller does not need to change a single line of code.
1. Factory Method
Separately encapsulate the logic of "creating an object" into a function or class, and expose an "on-demand pickup" entrance to the caller.
Python minimalist implementation
Even classes are omitted here, and functions are directly used to return lambda or built-in classes:
✨ Advantages
- Shield creation details, the caller only cares about "what I want".
- To add a new type, you only need to add a branch to the factory, which complies with the opening and closing principle.
⚠️ Disadvantages
- In simple scenarios (always returning only one type) it will appear over-designed.
🎯 Applicable scenarios
- Dynamically select instances based on configuration, user input, or environment variables.
- API response format switching (JSON/XML/Protobuf).
2. Abstract Factory
An upgraded version of the factory method - manages a set of interrelated objects that must be used in pairs (such as background color, text color, button style in "dark mode").
Python minimalist implementation
Taking advantage of Python's dynamic features, even the abstract base class can be omitted (it is recommended to retain it for large projects)abcconstraint):
✨ Advantages
- Force product families to be used together to ensure uniform style/function.
- Switching product families is like switching a factory object.
⚠️ Disadvantages
- Adding a new product family requires modifying all factory codes, and the expansion cost is high.
🎯 Applicable scenarios
- UI skinning system (dark/light/high contrast themes).
- Multi-database driver adaptation (MySQL/PostgreSQL/Oracle).
- Multi-language translation component switching.
3. Lazy Initialization (Lazy Evaluation)
Objects or data are not prepared in advance and are only loaded when they are actually used for the first time - especially suitable for scenarios where "memory/resources are expensive and may never be used".
Python minimalist implementation
use@propertyDecorators hide loading logic behind property access:
✨ Advantages
- Reduce startup time and initial memory usage.
- There is no need for external callers to care about "whether it has been initialized".
⚠️ Disadvantages
- There is a noticeable delay on the first visit.
- Natural threads are not safe (may be loaded repeatedly under multi-threading) and need to be locked.
🎯 Applicable scenarios
- Load very large files or parse complex configurations.
- Establish expensive database/network connections.
- Import large data processing modules on demand.
4. Singleton mode (Singleton)
Ensure that the class has only one instance throughout the entire program life cycle - suitable for components that require "global unique shared state".
Python minimalist implementation
Using metaclasses to control the instance creation process is concise and relatively safe:
✨ Advantages
- Save memory and ensure that the global state is unique.
- Avoid side effects caused by repeated initialization.
⚠️ Disadvantages
- Violates the single responsibility principle (the class must manage both business and singleton control).
- Difficulty in testing (global state easily causes cross-contamination of tests).
- Multi-threaded environments require additional locking.
🎯 Applicable scenarios
- Global configuration management.
- Database connection pool.
- Logger.
2. Structural Patterns
Core Goal: Through class inheritance/object combination, scattered small classes can be flexibly assembled into a more powerful structure - you can add functions and change structures without changing the original code.
5. Decorator mode (Decorator)
Dynamically add extra functionality to an object or function - more flexible than creating a subclass, and you can add multiple decorators in any order.
Python native support!
use@Syntactic sugar, implement function decorator:
✨ Advantages
- Dynamic overlay function without changing the original function code.
- Highly compliant with the opening and closing principle, the decorators can be freely combined.
⚠️ Disadvantages
- Multiple levels of nesting reduce debugging readability.
- May lose meta-information of the original function (available
functools.wrapsreserve).
🎯 Applicable scenarios
- Logging, performance monitoring, and permission verification.
- Data formatting (e.g. HTML escaping, encryption).
- Cache warm-up and retry mechanism.
3. Behavioral Patterns
Core Goal: Focus on "how objects communicate" and "how responsibilities are allocated" - making code communication clearer, responsibilities more single, and expansion easier.
6. Iterator pattern (Iterator)
Access the elements in the collection sequentially, but completely hide the internal implementation - Python native containers basically support it.
Python native usage + custom iterator
✨ Advantages
- unification
for ... ininterface, does not expose internal storage structures. - Supports lazy evaluation and can generate data on demand.
⚠️ Disadvantages
- for simple
list/dict, handwritten iterators appear redundant. - Pay attention to handling
StopIteration, otherwise it will cause an infinite loop.
🎯 Applicable scenarios
- Traverse the large table records in the database (return one by one, not load all at once).
- Handle large streaming files.
- Customize traversal of complex data structures (trees, graphs, linked lists).
Summarize
The above six patterns are the most commonly used design pattern models in Python projects and best reflect the simplicity of the language. The code given in this article removes lengthy abstract classes and interfaces, and uses functions, closures, metaclasses,@propertyWait for Python features to be replaced, allowing you to implement classic mode with minimal template code.
I hope this tutorial can help you quickly understand the essence of these patterns and apply them flexibly in actual development. If you want to dive into more examples (agents, observers, commands, etc.), you are welcome to go to faif/python-patterns to continue exploring.

