Abstraction
To charge a card, Shelfwise has to build an HTTP request, sign it with a secret key, send it, wait, retry if the network hiccups, and translate the provider's error codes. The checkout code should not know any of that. It wants to say one thing: "charge this card this amount". Abstraction lets it say exactly that.
The rule
Show what it does; hide how it does it.
An abstraction is a simplified view of something: the few operations a caller needs, with every detail of how they work kept out of sight.
from abc import ABC, abstractmethod
class PaymentGateway(ABC):
@abstractmethod
def charge(self, card, amount):
"""Charge the card; raise PaymentFailed if it is declined."""
class CardProviderGateway(PaymentGateway):
def charge(self, card, amount):
... # HTTP, signing, retries, error translationCheckout depends only on PaymentGateway.charge(card, amount). The abstract class declares what every gateway can do; the concrete class fills in how. Python's abc module stops anyone creating a PaymentGateway directly, since it has no real charge of its own.
Abstraction vs encapsulation. They work together but answer different questions:
- Encapsulation protects an object's state: nobody outside can break its rules.
- Abstraction simplifies an object's interface: callers see only what they need.
You meet abstraction everywhere. open("orders.csv") hides disk sectors and file systems. A car's steering wheel hides the steering rack. A good abstraction is one you can use correctly without ever looking inside. Its docstring states the promise, such as "raises PaymentFailed if declined", and that promise is all a caller needs.
Two things follow from depending on the simple view. You can swap the implementation (a different payment provider) without touching callers. And you can fake it in tests with a tiny FakeGateway that records charges instead of sending them.
The shortcut
Describe the thing without using the word "how", in terms the caller cares about. That sentence is your interface; everything else goes behind it.
Describe it for the caller
"Send this person a message with this subject and body."
The trap is the leaky abstraction: an interface like send(to, subject, body, http_timeout, retry_count) that drags the hidden details back out into every call.
Drills
Answer fast — trust the rule.
What does an abstraction hide?
How does abstraction differ from encapsulation?
Checkout depends only on PaymentGateway. What becomes easy?
Which interface leaks its hidden details?
Remember
- Show what it does; hide how it does it.
- Describe it without "how": that sentence is the interface.
- Trap: leaky interfaces that make callers pass implementation details.
