01
Make the main method tell the story
When an operation becomes complex, I want to understand its flow before I understand every implementation detail.
I tend to organize multi-step business logic around a small use-case or orchestration object with one clear public entry point. The top-level method should read like a summary of the operation. Detailed work stays in focused methods; when one step develops its own dependencies, rules, and failure modes, I pull it into a separate component.
Earlier in my career, I often stored every intermediate result on self. That made the control flow look clean, but it could hide which step produced the data consumed by the next one. These days I usually return and pass ordinary values explicitly. If a workflow genuinely has a lot of shared state, I would rather introduce a named execution or request context than keep adding implicit self attributes.
For a simple transformation, a plain function is usually better. I reach for this structure when an operation has enough steps that the flow itself becomes something worth making explicit.
class OrderCreator:
def create(self, request):
user = self._load_user(request)
order = self._build_order(request, user)
price = self._calculate_price(order)
payment = self._charge(user, price)
return self._finish(order, payment)The goal isn't to create more classes. It's to make complex code readable from the top down.