Abstractions are the best

Your code will be safer and more readable. It will prevent entire classes of bugs. It will be easier to add new features.

You can inject dependencies at runtime to make testing easy.

You can swap out your third party dependencies.

You can adapt quicker to business logic changes.

You can treat X and Y as the same thing. They’re both forms of Z, after all.

Abstractions are the worst

Your code will be fragile. It will be hard to debug as it jumps through the hoops you’ve added. You’ll add them too early. New engineers will need to learn your own bespoke methods.

Your dependency injection made it harder to add new dependencies, and you didn’t write tests anyway.

Your third party dependencies never changed, you just layered your own clunky interface over their nice one.

The business logic changed, but not in the way you planned for.

X and Y diverged more than expected, and now there’s 100 functions in your codebase where you have to check whether your Z is really an X or a Y.