I came here to say this. Attractions act as a bridge between things which allow those things to change independently.
Using an ORM allows my program to easily work against multiple sql databases. Using a compiler allows me to target different hardware. Using standard protocols allows me to communicate with different programs. Using libraries to do say email hides me from those protocols and allows me to adapt to service providers Using APIs not protocols.
In other words the abstraction is designed to hide a layer (which can change) from a program not interested in that level of change.
The key is to stop abstracting when the program cares. By all means encapsulate rules and processes, but they're a direct implementation of those rules and processes.
One can argue my "calculateLeaveForEmployee" function is an "abstraction" - but that would be a misnomer. Since there's only one set of rules in play (the set that matters now) its an implementation. An abstraction supports (at least) two things at the same time.