Composition over inheritance
Build behaviour by combining small parts, rather than stacking parent and child classes. Want a client that logs and retries? Wrap the client in something that adds each behaviour, rather than extending it.
To change an inherited class you have to read its parents, which spends context on files you aren't changing. Parts that are combined can be read, replaced and tested one at a time, including by an agent.
Say it to your agent
“Don't extend BaseClient again. Write withRetry(client) that returns an object with the same methods, and use it only at the one place that needs retries.”