โ Back to OOP Concepts
๐ญ
Pillars
Abstraction
Hides complex implementation details behind a simple, well-defined interface, exposing only what the caller needs.
The Problem
Without abstraction, callers must understand and depend on every implementation detail of a system, making code harder to use, change, and test โ and impossible to swap implementations.
How It Works
- โบAbstract classes/protocols/interfaces describe *what* an object does, not *how*
- โบConcrete implementations fill in the "how" behind the abstraction
- โบCallers program against the abstraction, enabling swappable implementations
- โบReduces cognitive load by exposing only relevant operations
When to Use
โDesigning public APIs or libraries
โSupporting multiple implementations behind one interface (e.g., payment providers)
โIsolating volatile subsystems behind a stable boundary
Real-World Examples
๐
iOS
Protocols like Codable and Equatable hide conformance details from callers
๐ค
Android
Repository interfaces hide whether data comes from Room or a network call
๐
Web
A Storage interface abstracting over localStorage, sessionStorage, or IndexedDB
Code Examples
Swift
protocol PaymentProcessor {
func pay(amount: Double)
}
class CreditCardProcessor: PaymentProcessor {
func pay(amount: Double) {
print("Charging $\(amount) to credit card")
}
}
class PayPalProcessor: PaymentProcessor {
func pay(amount: Double) {
print("Sending $\(amount) via PayPal")
}
}
func checkout(amount: Double, processor: PaymentProcessor) {
processor.pay(amount: amount)
}
checkout(amount: 49.99, processor: PayPalProcessor())