From 964f3f2da72961431057f5eb004064ca22565b58 Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Wed, 4 Mar 2026 22:22:31 +0300 Subject: [PATCH 1/7] docs: add mermaid diagrams --- README.md | 176 ++++++++++++++++++++---------------------------------- 1 file changed, 64 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index 4d12a2f1..a9db96bd 100644 --- a/README.md +++ b/README.md @@ -1,146 +1,98 @@ -python-patterns -=============== +# README.md — вставки с диаграммами Mermaid -A collection of design patterns and idioms in Python. +> Ниже показаны **три блока**, которые нужно вставить в `README.md` перед таблицей каждого раздела. +> Каждый блок отделён от окружающего текста пустой строкой (требование GitHub Markdown renderer). -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 ----------------- +## 🔵 Вставка 1 — перед таблицей **Creational Patterns** -__Creational Patterns__: +Место: сразу после строки `## Creational Patterns` и перед строкой `| Pattern | Description |` -| Pattern | Description | -|:-------:| ----------- | -| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic function with specific factories | -| [borg](patterns/creational/borg.py) | a singleton with shared-state among instances | -| [builder](patterns/creational/builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects | -| [factory](patterns/creational/factory.py) | delegate a specialized function/method to create instances | -| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | lazily-evaluated property pattern in Python | -| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of instances of the same type | -| [prototype](patterns/creational/prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) | - -__Structural Patterns__: +```markdown +## Creational Patterns -| Pattern | Description | -|:-------:| ----------- | -| [3-tier](patterns/structural/3-tier.py) | data<->business logic<->presentation separation (strict relationships) | -| [adapter](patterns/structural/adapter.py) | adapt one interface to another using a white-list | -| [bridge](patterns/structural/bridge.py) | a client-provider middleman to soften interface changes | -| [composite](patterns/structural/composite.py) | lets clients treat individual objects and compositions uniformly | -| [decorator](patterns/structural/decorator.py) | wrap functionality with other functionality in order to affect outputs | -| [facade](patterns/structural/facade.py) | use one class as an API to a number of others | -| [flyweight](patterns/structural/flyweight.py) | transparently reuse existing instances of objects with similar/identical state | -| [front_controller](patterns/structural/front_controller.py) | single handler requests coming to the application | -| [mvc](patterns/structural/mvc.py) | model<->view<->controller (non-strict relationships) | -| [proxy](patterns/structural/proxy.py) | an object funnels operations to something else | - -__Behavioral Patterns__: +> Patterns that deal with **object creation** — abstracting and controlling how instances are made. -| Pattern | Description | -|:-------:| ----------- | -| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | apply a chain of successive handlers to try and process the data | -| [catalog](patterns/behavioral/catalog.py) | general methods will call different specialized methods based on construction parameter | -| [chaining_method](patterns/behavioral/chaining_method.py) | continue callback next object method | -| [command](patterns/behavioral/command.py) | bundle a command and arguments to call later | -| [iterator](patterns/behavioral/iterator.py) | traverse a container and access the container's elements | -| [iterator](patterns/behavioral/iterator_alt.py) (alt. impl.)| traverse a container and access the container's elements | -| [mediator](patterns/behavioral/mediator.py) | an object that knows how to connect other objects and act as a proxy | -| [memento](patterns/behavioral/memento.py) | generate an opaque token that can be used to go back to a previous state | -| [observer](patterns/behavioral/observer.py) | provide a callback for notification of events/changes to data | -| [publish_subscribe](patterns/behavioral/publish_subscribe.py) | a source syndicates events/data to 0+ registered listeners | -| [registry](patterns/behavioral/registry.py) | keep track of all subclasses of a given class | -| [servant](patterns/behavioral/servant.py) | provide common functionality to a group of classes without using inheritance | -| [specification](patterns/behavioral/specification.py) | business rules can be recombined by chaining the business rules together using boolean logic | -| [state](patterns/behavioral/state.py) | logic is organized into a discrete number of potential states and the next state that can be transitioned to | -| [strategy](patterns/behavioral/strategy.py) | selectable operations over the same data | -| [template](patterns/behavioral/template.py) | an object imposes a structure but takes pluggable components | -| [visitor](patterns/behavioral/visitor.py) | invoke a callback for all items of a collection | - -__Design for Testability Patterns__: +```mermaid +graph LR + Client -->|requests object| AbstractFactory + AbstractFactory -->|delegates to| ConcreteFactory + ConcreteFactory -->|produces| Product -| Pattern | Description | -|:-------:| ----------- | -| [dependency_injection](patterns/dependency_injection.py) | 3 variants of dependency injection | + Builder -->|step-by-step| Director + Director -->|returns| BuiltObject -__Fundamental Patterns__: + FactoryMethod -->|subclass decides| ConcreteProduct + Pool -->|reuses| PooledInstance +``` | Pattern | Description | -|:-------:| ----------- | -| [delegation_pattern](patterns/fundamental/delegation_pattern.py) | an object handles a request by delegating to a second object (the delegate) | +``` -__Others__: +--- -| Pattern | Description | -|:-------:| ----------- | -| [blackboard](patterns/other/blackboard.py) | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern | -| [graph_search](patterns/other/graph_search.py) | graphing algorithms - non gang of four pattern | -| [hsm](patterns/other/hsm/hsm.py) | hierarchical state machine - non gang of four pattern | +## 🟢 Вставка 2 — перед таблицей **Structural Patterns** +Место: сразу после строки `## Structural Patterns` и перед строкой `| Pattern | Description |` -Videos ------- -[Design Patterns in Python by Peter Ullrich](https://www.youtube.com/watch?v=bsyjSW46TDg) +```markdown +## Structural Patterns -[Sebastian Buczyński - Why you don't need design patterns in Python?](https://www.youtube.com/watch?v=G5OeYHCJuv0) +> Patterns that define **how classes and objects are composed** to form larger, flexible structures. -[You Don't Need That!](https://www.youtube.com/watch?v=imW-trt0i9I) +```mermaid +graph TD + Client --> Facade + Facade --> SubsystemA + Facade --> SubsystemB + Facade --> SubsystemC -[Pluggable Libs Through Design Patterns](https://www.youtube.com/watch?v=PfgEU3W0kyU) + Client2 --> Adapter + Adapter --> LegacyService + Client3 --> Proxy + Proxy -->|controls access to| RealSubject -Contributing ------------- -When an implementation is added or modified, please review the following guidelines: + Component --> Composite + Composite --> Leaf1 + Composite --> Leaf2 +``` -##### 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](patterns/structural/facade.py) has a good example of detailed description, -but sometimes the shorter one as in [template.py](patterns/behavioral/template.py) would suffice. - -##### Python 2 compatibility -To see Python 2 compatible versions of some patterns please check-out the [legacy](https://github.com/faif/python-patterns/tree/legacy) tag. +| Pattern | Description | +``` -##### 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. +## 🟠 Вставка 3 — перед таблицей **Behavioral Patterns** -Then either: -- `tox` or `tox -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. +Место: сразу после строки `## Behavioral Patterns` и перед строкой `| Pattern | Description |` -You can also run `flake8` or `pytest` commands manually. Examples can be found in `tox.ini`. +```markdown +## Behavioral Patterns -## Contributing via issue triage [![Open Source Helpers](https://www.codetriage.com/faif/python-patterns/badges/users.svg)](https://www.codetriage.com/faif/python-patterns) +> Patterns concerned with **communication and responsibility** between objects. -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](https://www.codetriage.com/faif/python-patterns). +```mermaid +graph LR + Sender -->|sends event| Observer1 + Sender -->|sends event| Observer2 + Request --> Handler1 + Handler1 -->|passes if unhandled| Handler2 + Handler2 -->|passes if unhandled| Handler3 -## 🚫 Anti-Patterns + Context -->|delegates to| Strategy + Strategy -->|executes| Algorithm -This section lists some common design patterns that are **not recommended** in Python and explains why. + Originator -->|saves state to| Memento + Caretaker -->|holds| Memento +``` -### 🧱 Singleton -**Why not:** -- Python modules are already singletons — every module is imported only once. -- Explicit singleton classes add unnecessary complexity. -- Better alternatives: use module-level variables or dependency injection. +| Pattern | Description | +``` -### 🌀 God Object -**Why not:** -- Centralizes too much logic in a single class. -- Makes code harder to test and maintain. -- Better alternative: split functionality into smaller, cohesive classes. +--- -### 🔁 Inheritance overuse -**Why not:** -- Deep inheritance trees make code brittle. -- Prefer composition and delegation. -- “Favor composition over inheritance.” +> **Примечание для ревьюеров:** диаграммы намеренно упрощены — цель показать *ключевое взаимодействие* каждой группы, а не полную UML-схему каждого паттерна. Детали реализации — в `.py`-файлах. From f393fbd63ff021687b0ed3a74292b34a7e613689 Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Fri, 6 Mar 2026 21:57:09 +0300 Subject: [PATCH 2/7] Update README.md --- README.md | 55 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index a9db96bd..ba563ae8 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,7 @@ -# README.md — вставки с диаграммами Mermaid +# python-patterns -> Ниже показаны **три блока**, которые нужно вставить в `README.md` перед таблицей каждого раздела. -> Каждый блок отделён от окружающего текста пустой строкой (требование GitHub Markdown renderer). +A collection of design patterns and idioms in Python. ---- - -## 🔵 Вставка 1 — перед таблицей **Creational Patterns** - -Место: сразу после строки `## Creational Patterns` и перед строкой `| Pattern | Description |` - -```markdown ## Creational Patterns > Patterns that deal with **object creation** — abstracting and controlling how instances are made. @@ -25,23 +17,6 @@ graph LR FactoryMethod -->|subclass decides| ConcreteProduct Pool -->|reuses| PooledInstance -``` - -| Pattern | Description | -``` - ---- - -## 🟢 Вставка 2 — перед таблицей **Structural Patterns** - -Место: сразу после строки `## Structural Patterns` и перед строкой `| Pattern | Description |` - -```markdown -## Structural Patterns - -> Patterns that define **how classes and objects are composed** to form larger, flexible structures. - -```mermaid graph TD Client --> Facade Facade --> SubsystemA @@ -57,23 +32,6 @@ graph TD Component --> Composite Composite --> Leaf1 Composite --> Leaf2 -``` - -| Pattern | Description | -``` - ---- - -## 🟠 Вставка 3 — перед таблицей **Behavioral Patterns** - -Место: сразу после строки `## Behavioral Patterns` и перед строкой `| Pattern | Description |` - -```markdown -## Behavioral Patterns - -> Patterns concerned with **communication and responsibility** between objects. - -```mermaid graph LR Sender -->|sends event| Observer1 Sender -->|sends event| Observer2 @@ -87,12 +45,3 @@ graph LR Originator -->|saves state to| Memento Caretaker -->|holds| Memento -``` - -| Pattern | Description | -``` - ---- - -> **Примечание для ревьюеров:** диаграммы намеренно упрощены — цель показать *ключевое взаимодействие* каждой группы, а не полную UML-схему каждого паттерна. Детали реализации — в `.py`-файлах. - From cf4fd6d9863a4b2c84d78443f87e395d768711e7 Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Mon, 9 Mar 2026 11:57:29 +0300 Subject: [PATCH 3/7] docs: add mermaid diagrams --- README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/README.md b/README.md index ba563ae8..11190a36 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,24 @@ graph LR FactoryMethod -->|subclass decides| ConcreteProduct Pool -->|reuses| PooledInstance +``` + +| Pattern | Description | +|:------- |:----------- | +| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic interface to create a family of related objects | +| [borg](patterns/creational/borg.py) | a singleton with shared-state among instances | +| [builder](patterns/creational/builder.py) | instead of using complex constructors, isolate the construction of an object and make it multi-step | +| [factory](patterns/creational/factory.py) | delegate the creation of objects to specialized methods or classes | +| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | wait until the value is needed to calculate it | +| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of objects of the same type | +| [prototype](patterns/creational/prototype.py) | use a factory to create new objects by copying an existing instance | +| [singleton](patterns/creational/singleton.py) | restrict the instantiation of a class to one object | + +## Structural Patterns + +> Patterns that define **how classes and objects are composed** to form larger, flexible structures. + +```mermaid graph TD Client --> Facade Facade --> SubsystemA @@ -32,6 +50,26 @@ graph TD Component --> Composite Composite --> Leaf1 Composite --> Leaf2 +``` + +| Pattern | Description | +|:------- |:----------- | +| [3-tier](patterns/structural/3-tier.py) | data<->business logic<->presentation separation (strict relationships) | +| [adapter](patterns/structural/adapter.py) | adapt one interface to another using a white-box wrapper | +| [bridge](patterns/structural/bridge.py) | decouple an abstraction from its implementation | +| [composite](patterns/structural/composite.py) | encapsulate a group of objects into a single object | +| [decorator](patterns/structural/decorator.py) | wrap a class to add new functionality without changing its structure | +| [facade](patterns/structural/facade.py) | provide a simplified interface to a complex system | +| [flyweight](patterns/structural/flyweight.py) | use sharing to support a large number of objects efficiently | +| [front_controller](patterns/structural/front_controller.py) | a single entry point for all requests to an application | +| [proxy](patterns/structural/proxy.py) | an object representing another object | +| [mvc](patterns/structural/mvc.py) | separate data (model), user interface (view), and logic (controller) | + +## Behavioral Patterns + +> Patterns concerned with **communication and responsibility** between objects. + +```mermaid graph LR Sender -->|sends event| Observer1 Sender -->|sends event| Observer2 @@ -45,3 +83,23 @@ graph LR Originator -->|saves state to| Memento Caretaker -->|holds| Memento +``` + +| Pattern | Description | +|:------- |:----------- | +| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | allow multiple objects to handle a request without them needing to know about each other | +| [command](patterns/behavioral/command.py) | encapsulate a request as an object, allowing for parameterization and queuing | +| [catalog](patterns/behavioral/catalog.py) | a class that allows looking up other classes based on various criteria | +| [chaining_method](patterns/behavioral/chaining_method.py) | allow calling multiple methods on the same object in a single statement | +| [interpreter](patterns/behavioral/interpreter.py) | define a grammar for a language and use it to interpret statements | +| [iterator](patterns/behavioral/iterator.py) | provide a way to access elements of a collection sequentially | +| [mediator](patterns/behavioral/mediator.py) | encapsulate how a set of objects interact | +| [memento](patterns/behavioral/memento.py) | capture and restore an object's internal state | +| [observer](patterns/behavioral/observer.py) | allow objects to notify other objects about changes in their state | +| [publish_subscribe](patterns/behavioral/publish_subscribe.py) | allow objects to subscribe to events and receive notifications when they occur | +| [registry](patterns/behavioral/registry.py) | keep track of all instances of a class | +| [specification](patterns/behavioral/specification.py) | define a set of criteria that an object must meet | +| [state](patterns/behavioral/state.py) | allow an object to change its behavior when its internal state changes | +| [strategy](patterns/behavioral/strategy.py) | define a family of algorithms and make them interchangeable | +| [template](patterns/behavioral/template.py) | define the skeleton of an algorithm in a method, allowing subclasses to override specific steps | +| [visitor](patterns/behavioral/visitor.py) | separate an algorithm from the object structure it operates on | From d40a4230b1f217f5bf35e4859e33e345c8b25162 Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Mon, 9 Mar 2026 11:58:56 +0300 Subject: [PATCH 4/7] docs: add mermaid diagrams From f311afdfb2e01afd661519d65b402a61e8f61c91 Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Mon, 9 Mar 2026 12:03:24 +0300 Subject: [PATCH 5/7] docs: add mermaid diagrams --- README.md | 121 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 11190a36..89131573 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ 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. + ## Creational Patterns > Patterns that deal with **object creation** — abstracting and controlling how instances are made. @@ -20,14 +22,14 @@ graph LR ``` | Pattern | Description | -|:------- |:----------- | -| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic interface to create a family of related objects | +|:-------:| ----------- | +| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic function with specific factories | | [borg](patterns/creational/borg.py) | a singleton with shared-state among instances | -| [builder](patterns/creational/builder.py) | instead of using complex constructors, isolate the construction of an object and make it multi-step | -| [factory](patterns/creational/factory.py) | delegate the creation of objects to specialized methods or classes | -| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | wait until the value is needed to calculate it | -| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of objects of the same type | -| [prototype](patterns/creational/prototype.py) | use a factory to create new objects by copying an existing instance | +| [builder](patterns/creational/builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects | +| [factory](patterns/creational/factory.py) | delegate a specialized function/method to create instances | +| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | lazily-evaluated property pattern in Python | +| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of instances of the same type | +| [prototype](patterns/creational/prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) | | [singleton](patterns/creational/singleton.py) | restrict the instantiation of a class to one object | ## Structural Patterns @@ -53,17 +55,17 @@ graph TD ``` | Pattern | Description | -|:------- |:----------- | +|:-------:| ----------- | | [3-tier](patterns/structural/3-tier.py) | data<->business logic<->presentation separation (strict relationships) | -| [adapter](patterns/structural/adapter.py) | adapt one interface to another using a white-box wrapper | -| [bridge](patterns/structural/bridge.py) | decouple an abstraction from its implementation | -| [composite](patterns/structural/composite.py) | encapsulate a group of objects into a single object | -| [decorator](patterns/structural/decorator.py) | wrap a class to add new functionality without changing its structure | -| [facade](patterns/structural/facade.py) | provide a simplified interface to a complex system | -| [flyweight](patterns/structural/flyweight.py) | use sharing to support a large number of objects efficiently | -| [front_controller](patterns/structural/front_controller.py) | a single entry point for all requests to an application | -| [proxy](patterns/structural/proxy.py) | an object representing another object | -| [mvc](patterns/structural/mvc.py) | separate data (model), user interface (view), and logic (controller) | +| [adapter](patterns/structural/adapter.py) | adapt one interface to another using a white-list | +| [bridge](patterns/structural/bridge.py) | a client-provider middleman to soften interface changes | +| [composite](patterns/structural/composite.py) | lets clients treat individual objects and compositions uniformly | +| [decorator](patterns/structural/decorator.py) | wrap functionality with other functionality in order to affect outputs | +| [facade](patterns/structural/facade.py) | use one class as an API to a number of others | +| [flyweight](patterns/structural/flyweight.py) | transparently reuse existing instances of objects with similar/identical state | +| [front_controller](patterns/structural/front_controller.py) | single handler requests coming to the application | +| [mvc](patterns/structural/mvc.py) | model<->view<->controller (non-strict relationships) | +| [proxy](patterns/structural/proxy.py) | an object funnels operations to something else | ## Behavioral Patterns @@ -86,20 +88,73 @@ graph LR ``` | Pattern | Description | -|:------- |:----------- | -| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | allow multiple objects to handle a request without them needing to know about each other | -| [command](patterns/behavioral/command.py) | encapsulate a request as an object, allowing for parameterization and queuing | -| [catalog](patterns/behavioral/catalog.py) | a class that allows looking up other classes based on various criteria | -| [chaining_method](patterns/behavioral/chaining_method.py) | allow calling multiple methods on the same object in a single statement | +|:-------:| ----------- | +| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | apply a chain of successive handlers to try and process the data | +| [catalog](patterns/behavioral/catalog.py) | general methods will call different specialized methods based on construction parameter | +| [chaining_method](patterns/behavioral/chaining_method.py) | continue callback next object method | +| [command](patterns/behavioral/command.py) | bundle a command and arguments to call later | | [interpreter](patterns/behavioral/interpreter.py) | define a grammar for a language and use it to interpret statements | -| [iterator](patterns/behavioral/iterator.py) | provide a way to access elements of a collection sequentially | -| [mediator](patterns/behavioral/mediator.py) | encapsulate how a set of objects interact | -| [memento](patterns/behavioral/memento.py) | capture and restore an object's internal state | -| [observer](patterns/behavioral/observer.py) | allow objects to notify other objects about changes in their state | -| [publish_subscribe](patterns/behavioral/publish_subscribe.py) | allow objects to subscribe to events and receive notifications when they occur | -| [registry](patterns/behavioral/registry.py) | keep track of all instances of a class | -| [specification](patterns/behavioral/specification.py) | define a set of criteria that an object must meet | -| [state](patterns/behavioral/state.py) | allow an object to change its behavior when its internal state changes | -| [strategy](patterns/behavioral/strategy.py) | define a family of algorithms and make them interchangeable | -| [template](patterns/behavioral/template.py) | define the skeleton of an algorithm in a method, allowing subclasses to override specific steps | -| [visitor](patterns/behavioral/visitor.py) | separate an algorithm from the object structure it operates on | +| [iterator](patterns/behavioral/iterator.py) | traverse a container and access the container's elements | +| [iterator](patterns/behavioral/iterator_alt.py) (alt. impl.)| traverse a container and access the container's elements | +| [mediator](patterns/behavioral/mediator.py) | an object that knows how to connect other objects and act as a proxy | +| [memento](patterns/behavioral/memento.py) | generate an opaque token that can be used to go back to a previous state | +| [observer](patterns/behavioral/observer.py) | provide a callback for notification of events/changes to data | +| [publish_subscribe](patterns/behavioral/publish_subscribe.py) | a source syndicates events/data to 0+ registered listeners | +| [registry](patterns/behavioral/registry.py) | keep track of all subclasses of a given class | +| [servant](patterns/behavioral/servant.py) | provide common functionality to a group of classes without using inheritance | +| [specification](patterns/behavioral/specification.py) | business rules can be recombined by chaining the business rules together using boolean logic | +| [state](patterns/behavioral/state.py) | logic is organized into a discrete number of potential states and the next state that can be transitioned to | +| [strategy](patterns/behavioral/strategy.py) | selectable operations over the same data | +| [template](patterns/behavioral/template.py) | an object imposes a structure but takes pluggable components | +| [visitor](patterns/behavioral/visitor.py) | invoke a callback for all items of a collection | + +## Design for Testability Patterns + +| Pattern | Description | +|:-------:| ----------- | +| [dependency_injection](patterns/dependency_injection.py) | 3 variants of dependency injection | + +## Fundamental Patterns + +| Pattern | Description | +|:-------:| ----------- | +| [delegation_pattern](patterns/fundamental/delegation_pattern.py) | an object handles a request by delegating to a second object (the delegate) | + +## Others + +| Pattern | Description | +|:-------:| ----------- | +| [blackboard](patterns/other/blackboard.py) | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern | +| [graph_search](patterns/other/graph_search.py) | graphing algorithms - non gang of four pattern | +| [hsm](patterns/other/hsm/hsm.py) | hierarchical state machine - non gang of four pattern | + +## Videos + +* [Design Patterns in Python by Peter Ullrich](https://www.youtube.com/watch?v=bsyjSW46TDg) +* [Sebastian Buczyński - Why you don't need design patterns in Python?](https://www.youtube.com/watch?v=G5OeYHCJuv0) +* [You Don't Need That!](https://www.youtube.com/watch?v=imW-trt0i9I) +* [Pluggable Libs Through Design Patterns](https://www.youtube.com/watch?v=PfgEU3W0kyU) + +## 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](patterns/structural/facade.py) has a good example of detailed description, but sometimes the shorter one as in [template.py](patterns/behavioral/template.py) would suffice. + +##### Python 2 compatibility +To see Python 2 compatible versions of some patterns please check-out the [legacy](https://github.com/faif/python-patterns/tree/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. +- Either `tox` or `tox -e ci37` for unit tests. +- If you have a bash compatible shell, use `./lint.sh`. + +## Contributing via issue triage [![Open Source Helpers](https://www.codetriage.com/faif/python-patterns/badges/users.svg)](https://www.codetriage.com/faif/python-patterns) +You can triage issues and pull requests on [CodeTriage](https://www.codetriage.com/faif/python-patterns). From ce1cef06bbf3f624d7c3b1206674f5343ac6734c Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Mon, 9 Mar 2026 12:06:06 +0300 Subject: [PATCH 6/7] docs: add mermaid diagrams From f44674f1105ecca99209ec46882aa039887d6bb4 Mon Sep 17 00:00:00 2001 From: maxkrivachev-web Date: Mon, 9 Mar 2026 12:25:00 +0300 Subject: [PATCH 7/7] docs: add mermaid diagrams --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 89131573..f0ea743f 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,28 @@ graph LR | [graph_search](patterns/other/graph_search.py) | graphing algorithms - non gang of four pattern | | [hsm](patterns/other/hsm/hsm.py) | hierarchical state machine - non gang of four pattern | +## 🚫 Anti-Patterns + +This section lists some common design patterns that are **not recommended** in Python and explains why. + +### 🧱 Singleton +**Why not:** +- Python modules are already singletons — every module is imported only once. +- Explicit singleton classes add unnecessary complexity. +- Better alternatives: use module-level variables or dependency injection. + +### 🌀 God Object +**Why not:** +- Centralizes too much logic in a single class. +- Makes code harder to test and maintain. +- Better alternative: split functionality into smaller, cohesive classes. + +### 🔁 Inheritance overuse +**Why not:** +- Deep inheritance trees make code brittle. +- Prefer composition and delegation. +- “Favor composition over inheritance.” + ## Videos * [Design Patterns in Python by Peter Ullrich](https://www.youtube.com/watch?v=bsyjSW46TDg)