Skip to content

Commit f311afd

Browse files
docs: add mermaid diagrams
1 parent d40a423 commit f311afd

1 file changed

Lines changed: 88 additions & 33 deletions

File tree

README.md

Lines changed: 88 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
A collection of design patterns and idioms in Python.
44

5+
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.
6+
57
## Creational Patterns
68

79
> Patterns that deal with **object creation** — abstracting and controlling how instances are made.
@@ -20,14 +22,14 @@ graph LR
2022
```
2123

2224
| Pattern | Description |
23-
|:------- |:----------- |
24-
| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic interface to create a family of related objects |
25+
|:-------:| ----------- |
26+
| [abstract_factory](patterns/creational/abstract_factory.py) | use a generic function with specific factories |
2527
| [borg](patterns/creational/borg.py) | a singleton with shared-state among instances |
26-
| [builder](patterns/creational/builder.py) | instead of using complex constructors, isolate the construction of an object and make it multi-step |
27-
| [factory](patterns/creational/factory.py) | delegate the creation of objects to specialized methods or classes |
28-
| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | wait until the value is needed to calculate it |
29-
| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of objects of the same type |
30-
| [prototype](patterns/creational/prototype.py) | use a factory to create new objects by copying an existing instance |
28+
| [builder](patterns/creational/builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects |
29+
| [factory](patterns/creational/factory.py) | delegate a specialized function/method to create instances |
30+
| [lazy_evaluation](patterns/creational/lazy_evaluation.py) | lazily-evaluated property pattern in Python |
31+
| [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of instances of the same type |
32+
| [prototype](patterns/creational/prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) |
3133
| [singleton](patterns/creational/singleton.py) | restrict the instantiation of a class to one object |
3234

3335
## Structural Patterns
@@ -53,17 +55,17 @@ graph TD
5355
```
5456

5557
| Pattern | Description |
56-
|:------- |:----------- |
58+
|:-------:| ----------- |
5759
| [3-tier](patterns/structural/3-tier.py) | data<->business logic<->presentation separation (strict relationships) |
58-
| [adapter](patterns/structural/adapter.py) | adapt one interface to another using a white-box wrapper |
59-
| [bridge](patterns/structural/bridge.py) | decouple an abstraction from its implementation |
60-
| [composite](patterns/structural/composite.py) | encapsulate a group of objects into a single object |
61-
| [decorator](patterns/structural/decorator.py) | wrap a class to add new functionality without changing its structure |
62-
| [facade](patterns/structural/facade.py) | provide a simplified interface to a complex system |
63-
| [flyweight](patterns/structural/flyweight.py) | use sharing to support a large number of objects efficiently |
64-
| [front_controller](patterns/structural/front_controller.py) | a single entry point for all requests to an application |
65-
| [proxy](patterns/structural/proxy.py) | an object representing another object |
66-
| [mvc](patterns/structural/mvc.py) | separate data (model), user interface (view), and logic (controller) |
60+
| [adapter](patterns/structural/adapter.py) | adapt one interface to another using a white-list |
61+
| [bridge](patterns/structural/bridge.py) | a client-provider middleman to soften interface changes |
62+
| [composite](patterns/structural/composite.py) | lets clients treat individual objects and compositions uniformly |
63+
| [decorator](patterns/structural/decorator.py) | wrap functionality with other functionality in order to affect outputs |
64+
| [facade](patterns/structural/facade.py) | use one class as an API to a number of others |
65+
| [flyweight](patterns/structural/flyweight.py) | transparently reuse existing instances of objects with similar/identical state |
66+
| [front_controller](patterns/structural/front_controller.py) | single handler requests coming to the application |
67+
| [mvc](patterns/structural/mvc.py) | model<->view<->controller (non-strict relationships) |
68+
| [proxy](patterns/structural/proxy.py) | an object funnels operations to something else |
6769

6870
## Behavioral Patterns
6971

@@ -86,20 +88,73 @@ graph LR
8688
```
8789

8890
| Pattern | Description |
89-
|:------- |:----------- |
90-
| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | allow multiple objects to handle a request without them needing to know about each other |
91-
| [command](patterns/behavioral/command.py) | encapsulate a request as an object, allowing for parameterization and queuing |
92-
| [catalog](patterns/behavioral/catalog.py) | a class that allows looking up other classes based on various criteria |
93-
| [chaining_method](patterns/behavioral/chaining_method.py) | allow calling multiple methods on the same object in a single statement |
91+
|:-------:| ----------- |
92+
| [chain_of_responsibility](patterns/behavioral/chain_of_responsibility.py) | apply a chain of successive handlers to try and process the data |
93+
| [catalog](patterns/behavioral/catalog.py) | general methods will call different specialized methods based on construction parameter |
94+
| [chaining_method](patterns/behavioral/chaining_method.py) | continue callback next object method |
95+
| [command](patterns/behavioral/command.py) | bundle a command and arguments to call later |
9496
| [interpreter](patterns/behavioral/interpreter.py) | define a grammar for a language and use it to interpret statements |
95-
| [iterator](patterns/behavioral/iterator.py) | provide a way to access elements of a collection sequentially |
96-
| [mediator](patterns/behavioral/mediator.py) | encapsulate how a set of objects interact |
97-
| [memento](patterns/behavioral/memento.py) | capture and restore an object's internal state |
98-
| [observer](patterns/behavioral/observer.py) | allow objects to notify other objects about changes in their state |
99-
| [publish_subscribe](patterns/behavioral/publish_subscribe.py) | allow objects to subscribe to events and receive notifications when they occur |
100-
| [registry](patterns/behavioral/registry.py) | keep track of all instances of a class |
101-
| [specification](patterns/behavioral/specification.py) | define a set of criteria that an object must meet |
102-
| [state](patterns/behavioral/state.py) | allow an object to change its behavior when its internal state changes |
103-
| [strategy](patterns/behavioral/strategy.py) | define a family of algorithms and make them interchangeable |
104-
| [template](patterns/behavioral/template.py) | define the skeleton of an algorithm in a method, allowing subclasses to override specific steps |
105-
| [visitor](patterns/behavioral/visitor.py) | separate an algorithm from the object structure it operates on |
97+
| [iterator](patterns/behavioral/iterator.py) | traverse a container and access the container's elements |
98+
| [iterator](patterns/behavioral/iterator_alt.py) (alt. impl.)| traverse a container and access the container's elements |
99+
| [mediator](patterns/behavioral/mediator.py) | an object that knows how to connect other objects and act as a proxy |
100+
| [memento](patterns/behavioral/memento.py) | generate an opaque token that can be used to go back to a previous state |
101+
| [observer](patterns/behavioral/observer.py) | provide a callback for notification of events/changes to data |
102+
| [publish_subscribe](patterns/behavioral/publish_subscribe.py) | a source syndicates events/data to 0+ registered listeners |
103+
| [registry](patterns/behavioral/registry.py) | keep track of all subclasses of a given class |
104+
| [servant](patterns/behavioral/servant.py) | provide common functionality to a group of classes without using inheritance |
105+
| [specification](patterns/behavioral/specification.py) | business rules can be recombined by chaining the business rules together using boolean logic |
106+
| [state](patterns/behavioral/state.py) | logic is organized into a discrete number of potential states and the next state that can be transitioned to |
107+
| [strategy](patterns/behavioral/strategy.py) | selectable operations over the same data |
108+
| [template](patterns/behavioral/template.py) | an object imposes a structure but takes pluggable components |
109+
| [visitor](patterns/behavioral/visitor.py) | invoke a callback for all items of a collection |
110+
111+
## Design for Testability Patterns
112+
113+
| Pattern | Description |
114+
|:-------:| ----------- |
115+
| [dependency_injection](patterns/dependency_injection.py) | 3 variants of dependency injection |
116+
117+
## Fundamental Patterns
118+
119+
| Pattern | Description |
120+
|:-------:| ----------- |
121+
| [delegation_pattern](patterns/fundamental/delegation_pattern.py) | an object handles a request by delegating to a second object (the delegate) |
122+
123+
## Others
124+
125+
| Pattern | Description |
126+
|:-------:| ----------- |
127+
| [blackboard](patterns/other/blackboard.py) | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern |
128+
| [graph_search](patterns/other/graph_search.py) | graphing algorithms - non gang of four pattern |
129+
| [hsm](patterns/other/hsm/hsm.py) | hierarchical state machine - non gang of four pattern |
130+
131+
## Videos
132+
133+
* [Design Patterns in Python by Peter Ullrich](https://www.youtube.com/watch?v=bsyjSW46TDg)
134+
* [Sebastian Buczyński - Why you don't need design patterns in Python?](https://www.youtube.com/watch?v=G5OeYHCJuv0)
135+
* [You Don't Need That!](https://www.youtube.com/watch?v=imW-trt0i9I)
136+
* [Pluggable Libs Through Design Patterns](https://www.youtube.com/watch?v=PfgEU3W0kyU)
137+
138+
## Contributing
139+
140+
When an implementation is added or modified, please review the following guidelines:
141+
142+
##### Docstrings
143+
Add module level description in form of a docstring with links to corresponding references or other useful information.
144+
Add "Examples in Python ecosystem" section if you know some. It shows how patterns could be applied to real-world problems.
145+
[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.
146+
147+
##### Python 2 compatibility
148+
To see Python 2 compatible versions of some patterns please check-out the [legacy](https://github.com/faif/python-patterns/tree/legacy) tag.
149+
150+
##### Update README
151+
When everything else is done - update corresponding part of README.
152+
153+
##### Travis CI
154+
Please run the following before submitting a patch:
155+
- `black .` This lints your code.
156+
- Either `tox` or `tox -e ci37` for unit tests.
157+
- If you have a bash compatible shell, use `./lint.sh`.
158+
159+
## Contributing via issue triage [![Open Source Helpers](https://www.codetriage.com/faif/python-patterns/badges/users.svg)](https://www.codetriage.com/faif/python-patterns)
160+
You can triage issues and pull requests on [CodeTriage](https://www.codetriage.com/faif/python-patterns).

0 commit comments

Comments
 (0)