Abstractions are key to taming architectural complexity.

You can think of an abstraction as a boundary between tight internal coupling and loose external coupling. A choke point through which unrelated modules talk to a piece of functionality.

A good abstraction hides details and makes them unimportant. You call a function, it does the thing, and you don’t care how. The opposite of lasagna or minestrone code.