Top Related Projects
An ultra-simplified explanation to design patterns
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
Design patterns implemented in Java
A curated list of software and architecture related design patterns.
Everything you need to know to get the job.
📝 Algorithms and data structures implemented in JavaScript with explanations and links to further readings
Quick Overview
The python-patterns
repository on GitHub is a collection of design patterns and idioms in Python. It provides a comprehensive overview of various design patterns and their implementation in the Python programming language. The repository serves as a valuable resource for developers looking to enhance their understanding and application of design patterns in their Python projects.
Pros
- Comprehensive Coverage: The repository covers a wide range of design patterns, including Creational, Structural, and Behavioral patterns, providing a thorough exploration of these concepts in the context of Python.
- Practical Examples: Each design pattern is accompanied by clear and concise code examples, making it easier for developers to understand the practical application of these patterns.
- Active Community: The project has an active community of contributors, ensuring regular updates and improvements to the content.
- Educational Resource: The repository can be an excellent learning resource for developers, especially those new to design patterns or Python, as it offers a structured and organized way to explore these concepts.
Cons
- Lack of Detailed Explanations: While the code examples are helpful, the repository could benefit from more detailed explanations and discussions of the design patterns, their use cases, and their trade-offs.
- Uneven Quality: The quality and depth of the examples may vary across different design patterns, as the repository is a community-driven project.
- Potential Outdated Content: As with any community-driven project, there is a risk of some content becoming outdated over time, especially with the rapid evolution of Python and its ecosystem.
- Limited Practical Guidance: The repository focuses more on the theoretical aspects of design patterns and their implementation, and may lack practical guidance on how to apply them in real-world scenarios.
Code Examples
Here are a few code examples from the python-patterns
repository:
Singleton Pattern
The Singleton pattern ensures that a class has only one instance and provides a global point of access to it.
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
Factory Method Pattern
The Factory Method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate.
class Pizza:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
class CheesePizza(Pizza):
def __init__(self):
super().__init__("Cheese Pizza")
class VeggiePizza(Pizza):
def __init__(self):
super().__init__("Veggie Pizza")
class PizzaFactory:
@staticmethod
def create_pizza(pizza_type):
if pizza_type == "cheese":
return CheesePizza()
elif pizza_type == "veggie":
return VeggiePizza()
else:
raise ValueError("Invalid pizza type")
Observer Pattern
The Observer pattern defines a one-to-many dependency between objects, so that when one object changes state, all its dependents are notified and updated automatically.
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self):
for observer in self._observers:
observer.update(self)
class ConcreteSubject(Subject):
def __init__(self, initial_state):
super().__init__()
self._state = initial_state
@property
def state(self):
return self._state
@state.setter
def state(self, value):
self._state = value
self.notify()
class Observer:
def update(self, subject):
print(f"Observed state change: {subject.state}")
Getting Started
To get started with the python-patterns
repository, follow these steps:
-
Clone the repository to your local machine:
git clone https://github.com/faif/python-patterns.git
-
Navigate to the project directory:
Competitor Comparisons
An ultra-simplified explanation to design patterns
Pros of design-patterns-for-humans
- Written in plain English, making it more accessible to beginners
- Covers a wide range of design patterns with real-world examples
- Includes visual diagrams to illustrate pattern structures
Cons of design-patterns-for-humans
- Examples are in PHP, which may not be ideal for Python developers
- Less comprehensive coverage of patterns compared to python-patterns
- Lacks detailed implementation code for some patterns
Code Comparison
python-patterns (Strategy Pattern):
class QuackStrategy(object):
def quack(self):
pass
class LoudQuackStrategy(QuackStrategy):
def quack(self):
return "QUACK!"
design-patterns-for-humans (Strategy Pattern):
interface SortStrategy {
public function sort(array $dataset): array;
}
class BubbleSortStrategy implements SortStrategy {
public function sort(array $dataset): array {
// Sorting logic here
}
}
Both repositories aim to explain design patterns, but python-patterns focuses on Python implementations, while design-patterns-for-humans provides a more general overview with PHP examples. python-patterns offers more extensive code samples, whereas design-patterns-for-humans emphasizes simplicity and accessibility for beginners.
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
Pros of system-design-primer
- Comprehensive coverage of system design concepts and principles
- Includes interactive diagrams and visual aids for better understanding
- Provides real-world examples and case studies of large-scale systems
Cons of system-design-primer
- Focuses on high-level system design rather than specific programming patterns
- May be overwhelming for beginners due to its extensive content
- Less hands-on coding examples compared to python-patterns
Code comparison
While a direct code comparison isn't particularly relevant due to the different focus of these repositories, here's a brief example of how they differ in approach:
python-patterns (Strategy pattern):
class Strategy:
def __init__(self, func=None):
self.name = "Default Strategy"
if func:
self.execute = func
def execute(self):
print(f"{self.name} is used!")
system-design-primer (System design example):
Client -> DNS -> Load Balancer -> Web Server -> Application Server -> Database
The python-patterns repository focuses on implementing design patterns in Python, while system-design-primer provides high-level system architecture diagrams and explanations.
Design patterns implemented in Java
Pros of java-design-patterns
- More comprehensive, covering a wider range of design patterns
- Better organized with clear categorization and documentation
- Includes real-world examples and use cases for each pattern
Cons of java-design-patterns
- Larger codebase, potentially overwhelming for beginners
- Java-specific implementations may not translate easily to other languages
- More complex project structure due to its size and scope
Code Comparison
python-patterns (Strategy pattern):
class Strategy:
def __init__(self, function=None):
self.name = "Default Strategy"
if function:
self.execute = function
def execute(self):
print(f"{self.name} is used!")
java-design-patterns (Strategy pattern):
public interface Strategy {
int doOperation(int num1, int num2);
}
public class OperationAdd implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
Summary
Both repositories offer valuable resources for learning design patterns. python-patterns is more concise and Python-focused, making it easier for Python developers to grasp quickly. java-design-patterns provides a more extensive collection of patterns with detailed explanations and examples, but its Java-centric approach may require adaptation for use in other languages.
A curated list of software and architecture related design patterns.
Pros of awesome-design-patterns
- Covers a wide range of programming languages and design patterns
- Includes links to external resources and articles for deeper learning
- Provides a curated list of high-quality design pattern implementations
Cons of awesome-design-patterns
- Lacks detailed explanations or code examples within the repository
- May be overwhelming for beginners due to the large amount of information
Code comparison
python-patterns provides concrete Python implementations:
class Singleton:
__instance = None
def __new__(cls):
if cls.__instance is None:
cls.__instance = super().__new__(cls)
return cls.__instance
awesome-design-patterns doesn't include code examples directly, but links to external resources:
- [Singleton](https://en.wikipedia.org/wiki/Singleton_pattern)
- [Python Singleton](https://github.com/faif/python-patterns/blob/master/patterns/creational/singleton.py)
Summary
python-patterns focuses on Python-specific implementations with detailed explanations, while awesome-design-patterns offers a broader overview of design patterns across multiple languages. python-patterns is more suitable for Python developers looking for practical examples, whereas awesome-design-patterns serves as a comprehensive reference guide for various programming languages and paradigms.
Everything you need to know to get the job.
Pros of interviews
- Covers a broader range of topics including algorithms, data structures, and system design
- Includes solutions in multiple programming languages (Java, Python, C++)
- Provides a comprehensive resource for technical interview preparation
Cons of interviews
- Less focused on specific design patterns compared to python-patterns
- May not provide as in-depth explanations for each pattern or concept
- Could be overwhelming for beginners due to the large amount of content
Code Comparison
python-patterns (Strategy Pattern):
class Strategy:
def __init__(self, function=None):
self.name = "Default Strategy"
if function:
self.execute = function
def execute(self):
print(f"{self.name} is used!")
interviews (Binary Search Tree):
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
Both repositories provide valuable resources for developers, but they serve different purposes. python-patterns focuses on implementing design patterns in Python, while interviews covers a wider range of topics for technical interview preparation across multiple languages.
📝 Algorithms and data structures implemented in JavaScript with explanations and links to further readings
Pros of javascript-algorithms
- Extensive collection of algorithms and data structures
- Well-organized with detailed explanations and complexity analysis
- Includes unit tests for each implementation
Cons of javascript-algorithms
- Focused solely on algorithms, lacking design patterns
- May be overwhelming for beginners due to its comprehensive nature
Code Comparison
python-patterns (Strategy Pattern):
class Strategy:
def __init__(self, func=None):
self.name = "Default Strategy"
if func:
self.execute = func
def execute(self):
print(f"{self.name} is used!")
javascript-algorithms (Binary Search):
function binarySearch(sortedArray, seekElement) {
let startIndex = 0;
let endIndex = sortedArray.length - 1;
while (startIndex <= endIndex) {
const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2);
// ... (implementation continues)
}
}
Summary
While python-patterns focuses on design patterns in Python, javascript-algorithms provides a comprehensive collection of algorithms and data structures in JavaScript. The latter offers more depth in terms of algorithmic implementations but lacks coverage of design patterns. python-patterns is more suitable for learning software design principles, while javascript-algorithms is better for studying specific algorithms and their implementations.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
python-patterns
A collection of design patterns and idioms in Python.
Remember that each pattern has its own trade-offs. And you need to pay attention more to why you're choosing a certain pattern than to how to implement it.
Current Patterns
Creational Patterns:
Pattern | Description |
---|---|
abstract_factory | use a generic function with specific factories |
borg | a singleton with shared-state among instances |
builder | instead of using multiple constructors, builder object receives parameters and returns constructed objects |
factory | delegate a specialized function/method to create instances |
lazy_evaluation | lazily-evaluated property pattern in Python |
pool | preinstantiate and maintain a group of instances of the same type |
prototype | use a factory and clones of a prototype for new instances (if instantiation is expensive) |
Structural Patterns:
Pattern | Description |
---|---|
3-tier | data<->business logic<->presentation separation (strict relationships) |
adapter | adapt one interface to another using a white-list |
bridge | a client-provider middleman to soften interface changes |
composite | lets clients treat individual objects and compositions uniformly |
decorator | wrap functionality with other functionality in order to affect outputs |
facade | use one class as an API to a number of others |
flyweight | transparently reuse existing instances of objects with similar/identical state |
front_controller | single handler requests coming to the application |
mvc | model<->view<->controller (non-strict relationships) |
proxy | an object funnels operations to something else |
Behavioral Patterns:
Pattern | Description |
---|---|
chain_of_responsibility | apply a chain of successive handlers to try and process the data |
catalog | general methods will call different specialized methods based on construction parameter |
chaining_method | continue callback next object method |
command | bundle a command and arguments to call later |
iterator | traverse a container and access the container's elements |
iterator (alt. impl.) | traverse a container and access the container's elements |
mediator | an object that knows how to connect other objects and act as a proxy |
memento | generate an opaque token that can be used to go back to a previous state |
observer | provide a callback for notification of events/changes to data |
publish_subscribe | a source syndicates events/data to 0+ registered listeners |
registry | keep track of all subclasses of a given class |
specification | business rules can be recombined by chaining the business rules together using boolean logic |
state | logic is organized into a discrete number of potential states and the next state that can be transitioned to |
strategy | selectable operations over the same data |
template | an object imposes a structure but takes pluggable components |
visitor | invoke a callback for all items of a collection |
Design for Testability Patterns:
Pattern | Description |
---|---|
dependency_injection | 3 variants of dependency injection |
Fundamental Patterns:
Pattern | Description |
---|---|
delegation_pattern | an object handles a request by delegating to a second object (the delegate) |
Others:
Pattern | Description |
---|---|
blackboard | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern |
graph_search | graphing algorithms - non gang of four pattern |
hsm | hierarchical state machine - non gang of four pattern |
Videos
Design Patterns in Python by Peter Ullrich
Sebastian BuczyÅski - Why you don't need design patterns in Python?
Pluggable Libs Through Design Patterns
Contributing
When an implementation is added or modified, please review the following guidelines:
Docstrings
Add module level description in form of a docstring with links to corresponding references or other useful information.
Add "Examples in Python ecosystem" section if you know some. It shows how patterns could be applied to real-world problems.
facade.py has a good example of detailed description, but sometimes the shorter one as in template.py would suffice.
Python 2 compatibility
To see Python 2 compatible versions of some patterns please check-out the legacy tag.
Update README
When everything else is done - update corresponding part of README.
Travis CI
Please run the following before submitting a patch
black .
This lints your code.
Then either:
tox
ortox -e ci37
This runs unit tests. see tox.ini for further details.- If you have a bash compatible shell use
./lint.sh
This script will lint and test your code. This script mirrors the CI pipeline actions.
You can also run flake8
or pytest
commands manually. Examples can be found in tox.ini
.
Contributing via issue triage
You can triage issues and pull requests which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to subscribe to python-patterns on CodeTriage.
AI codebase assistance
The folks at Mutable.ai have built an AI assistant that is codebase-aware. Give it a try
Top Related Projects
An ultra-simplified explanation to design patterns
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
Design patterns implemented in Java
A curated list of software and architecture related design patterns.
Everything you need to know to get the job.
📝 Algorithms and data structures implemented in JavaScript with explanations and links to further readings
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot