Software systems rarely fail because of a missing abstraction. More often, they become hard to change because the relationships between parts stop being obvious.
Start with the grain
Before introducing new layers, look at how the current code already wants to be organized. Naming, folder boundaries, and call patterns usually reveal a structure worth preserving.
Prefer visible seams
When you do need to separate concerns, make the seams easy to find:
- Keep public interfaces small
- Put the surprising details next to the decisions they support
- Avoid indirection that exists only to look tidy
Clear systems age better than clever ones.