A Hero’s Journey — Crafting our Clean Python Epic
Hi, there! My name is Anderson, I have working as Software Engineer for over 15 years and I'm passionate about this.
Today I will talk about best practices to develop a nice Python and reveal the magic behind best practices for developing applications, the Clean Architecture.
Python is the elegant language that making developer's hearts skip a beat. In this journey, we will consider Clean Architecture like a sprinkle some magic into our Python projects, keeping the code organized, testable, and enchantingly maintainable.
The Wizard Tower (Clean Architecture)
The Clean Architecture is like a well-structured wizard's tower, that is designed to keep your software organized and uncluttered. It will keep code remains independent of external frameworks and allows our project to grow without many problems. In this realm of software architecture, Clean Architecture reigns as the sage ruler of separation of concerns and testability. Into our code, each layer as a realm of its own, working harmoniously to create a harmonious world of functionality.
Layers of Wisdom
Entities: Magic Scrolls
In the heart of Clean Architecture lies the Entities. This layer we will keep safe the core of our business logic, then we will consider this like sacred artifact, immune to the volatile tides of the external change.
Use Cases: Enchanted Quests
The Use Cases will orchestrate the grand quests of our application, using the mystical magic it will do our application be better and more strong. Their will use the spells bring entities to life, ensuring that business rules and logic are followed to the letter.
Interfaces: The Bridge to All Realms
The interfaces can be use to connecting various realms. These are the contracts that every realm must honor. With this bridge, if the darkness corrupt the outside world, our core will not be corrupted.
Frameworks: Beyond the Enchanted Forest
Here we have the details of the outside world, from the Database Castles to the Bewitched Web Intefaces. The key is to ensure these realms don't overpower our core with their intricacies. Let them be harmonious keeping our rules to cross the bridges.
Crafting our Clean Python Epic
We will create an application using the concept discussed earlier.
Structure
It's only a simple example how we can organize our project to be more Clean, for keep our logic, I will follow what was said earlier, including keep the nomenclatures.
my_app/
├── app
│ ├── core/
│ │ ├── entities/
│ │ │ ├── user.py
│ │ │ └── ...
│ │ ├── usecases/
│ │ │ ├── user_usecases.py
│ │ │ └── ...
│ │ └── interfaces/
│ │ ├── user_repository.py
│ │ └── ...
│ │
│ └── frameworks/
│ ├── database/
│ │ ├── database_user_repository.py
│ │ └── ...
│ └── web/
│ └── ...
├── tests/
│ ├── test_usecases.py
│ ├── test_repositories.py
│ └── ...
└── main.py
Our core/entities/user.py has the definition about what is User to the solution:
class User:
def __init__(self, name, email, password):
self.name = name
self.email = email
self.password = password
Our core/interfaces/user_repository.py has the contract that need to be respected when we need to use in our solution:
from abc import ABC, abstractmethod
from core.entities.user import User
class UserRepository(ABC):
@abstractmethod
def save_user(self, user: User):
raise NotImplementedError
Our core/usecases/uc_register_user.py defines how the solution will do to register a user:
from core.entities.user import User
from core.interfaces.user_repository import UserRepository
class RegisterUserUseCase:
def __init__(self, user_repository: UserRepository):
self.user_repository = user_repository
def execute(self, name, email, password):
user = User(name, email, password)
self.user_repository.save_user(user)
Our frameworks/database/database_user_repository.py respects our contracts and will implements how-to-use of any framework:
from core.interfaces.repositories import UserRepository
class DatabaseUserRepository(UserRepository):
def __init__():
# Our logic
def save_user(self, user):
# Our database logic
Our main.py has the implementation using the framework:
from core.usecases.uc_register_user import RegisterUserUseCase
from frameworks.repositories.database_user_repository import DatabaseUserRepository
def main():
user_repository = DatabaseUserRepository()
register_user_usecase = RegisterUserUseCase(user_repository)
register_user_usecase.execute("Anderson", "anderson@example.com", "securepassword")
if __name__ == "__main__":
main()
Conclusion
And there we have it, dear reader! Clean Architecture, like an ancient spell, shapes your Python codebase into a harmonious symphony. Each layer, from Entities to Use Cases, dances to its own tune, yet united ballet of software craftsmanship.
So go forth, let the magic of Clean Architecture in Python lead you to a realm of software maintainable bliss!
Thank you for you attention. See you!