-
Notifications
You must be signed in to change notification settings - Fork 7k
Refactor: Major modernization with Python 3.12, Strict Typing, and CI/CD Infrastructure #472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Jorgeotero1998
wants to merge
11
commits into
faif:master
Choose a base branch
from
Jorgeotero1998:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
3993853
refactor: add type annotations to factory pattern
Jorgeotero1998 6434df5
refactor: add type annotations to abstract_factory, builder and adapter
Jorgeotero1998 212f347
refactor: professional type-hinting and modernization (State, Observe…
Jorgeotero1998 845185a
refactor: high-level architectural modernization (7 patterns: Composi…
Jorgeotero1998 7637767
refactor: complete patterns modernization (Flyweight, Prototype, Deco…
Jorgeotero1998 8ed0e6b
chore: complete modernization and setup CI/CD infrastructure with Git…
Jorgeotero1998 1409365
docs: upgrade README and add unit tests for core patterns
Jorgeotero1998 2acb096
fix: align formatting and linting with legacy project requirements
Jorgeotero1998 792b1d1
style: automated linting fix and import reorganization
Jorgeotero1998 dd53656
chore: simplify configuration to match upstream legacy linting
Jorgeotero1998 4975a9b
fix: revert to legacy-compatible syntax and formatting
Jorgeotero1998 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
docs: upgrade README and add unit tests for core patterns
- Loading branch information
commit 140936550eb33599f74ef3fd58709530977e806f
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| repos: | ||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| rev: v0.1.0 | ||
| hooks: | ||
| - id: ruff | ||
| args: [ --fix ] | ||
| - id: ruff-format |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,181 +1,14 @@ | ||
| # python-patterns | ||
| # Python Design Patterns - Modern Edition | ||
|
|
||
| A collection of design patterns and idioms in Python. | ||
| Este repositorio contiene implementaciones de patrones de diseño clásicos, refactorizados integralmente para **Python 3.12**. | ||
|
|
||
| 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. | ||
| ## 🚀 Mejoras de Ingeniería Realizadas | ||
| - **Tipado Estricto:** Implementación de `typing.Protocol`, `Self`, y `Generics`. | ||
| - **Arquitectura:** Uso de Clases Base Abstractas (`abc.ABC`) para asegurar contratos de interfaz. | ||
| - **Gestión de Memoria:** Optimización de patrones estructurales mediante `weakref`. | ||
| - **CI/CD:** Pipeline automatizado con GitHub Actions para ejecución de tests y linting con Ruff. | ||
|
|
||
| ## Creational Patterns | ||
|
|
||
| > Patterns that deal with **object creation** — abstracting and controlling how instances are made. | ||
|
|
||
| ```mermaid | ||
| graph LR | ||
| Client -->|requests object| AbstractFactory | ||
| AbstractFactory -->|delegates to| ConcreteFactory | ||
| ConcreteFactory -->|produces| Product | ||
|
|
||
| Builder -->|step-by-step| Director | ||
| Director -->|returns| BuiltObject | ||
|
|
||
| FactoryMethod -->|subclass decides| ConcreteProduct | ||
| Pool -->|reuses| PooledInstance | ||
| ``` | ||
|
|
||
| | 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 | ||
|
|
||
| > Patterns that define **how classes and objects are composed** to form larger, flexible structures. | ||
|
|
||
| ```mermaid | ||
| graph TD | ||
| Client --> Facade | ||
| Facade --> SubsystemA | ||
| Facade --> SubsystemB | ||
| Facade --> SubsystemC | ||
|
|
||
| Client2 --> Adapter | ||
| Adapter --> LegacyService | ||
|
|
||
| Client3 --> Proxy | ||
| Proxy -->|controls access to| RealSubject | ||
|
|
||
| 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-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 concerned with **communication and responsibility** between objects. | ||
|
|
||
| ```mermaid | ||
| graph LR | ||
| Sender -->|sends event| Observer1 | ||
| Sender -->|sends event| Observer2 | ||
|
|
||
| Request --> Handler1 | ||
| Handler1 -->|passes if unhandled| Handler2 | ||
| Handler2 -->|passes if unhandled| Handler3 | ||
|
|
||
| Context -->|delegates to| Strategy | ||
| Strategy -->|executes| Algorithm | ||
|
|
||
| Originator -->|saves state to| Memento | ||
| Caretaker -->|holds| Memento | ||
| ``` | ||
|
|
||
| | 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 | | ||
| | [interpreter](patterns/behavioral/interpreter.py) | define a grammar for a language and use it to interpret statements | | ||
| | [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 | | ||
|
|
||
| ## 🚫 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) | ||
| * [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 [](https://www.codetriage.com/faif/python-patterns) | ||
| You can triage issues and pull requests on [CodeTriage](https://www.codetriage.com/faif/python-patterns). | ||
| ## 🛠 Stack de Calidad | ||
| - **Linter:** Ruff (High-performance Python linter). | ||
| - **Type Checker:** Mypy (Static type analysis). | ||
| - **Testing:** Pytest con cobertura de código. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import pytest | ||
| from patterns.creational.factory import GreekGetter, EnglishGetter | ||
| from patterns.behavioral.strategy import Order, ten_percent_discount | ||
|
|
||
| def test_factory_logic(): | ||
| greek = GreekGetter() | ||
| english = EnglishGetter() | ||
| assert "papadopoulos" in greek.trans["dog"] | ||
| assert "dog" in english.trans["dog"] | ||
|
|
||
| def test_strategy_logic(): | ||
| order = Order(100, ten_percent_discount) | ||
| assert order.apply_strategy() == 90.0 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Restore the original English descriptions