Encapsulation
Hide internal state behind controlled access — expose methods, not fields, so nothing outside the class can corrupt the object's integrity.
Intent & Description
🎯 Intent
External code that writes directly to internal fields can put an object in an invalid state. Encapsulation forces all modifications through methods that enforce invariants before applying changes.
📋 Context
A BankAccount with a public balance field can be set to any value by any caller — including -∞. Encapsulation makes callers use deposit() and withdraw() — the only paths that enforce the rule “balance can’t go negative.”
💡 Solution
Declare internal fields as private using access modifiers. Provide public methods (getters, setters, domain operations) that validate inputs before modifying state. The object’s invariants are enforced at its boundary — not relied upon by every caller.
Real-world Use Case
📌 TL;DR
Hide state, expose behavior. The object enforces its own invariants — callers can’t put it in an invalid state.
Advantages
- Invalid states become impossible — invariants are enforced at the boundary
- Internal implementation can change without breaking any caller
- Validation logic lives in one place, not scattered across every call site
- Easier to maintain and refactor — the surface area of change is the class itself
Disadvantages
- Adds boilerplate — getters, setters, and access modifiers for every field
- Fine-grained encapsulation can add overhead in performance-critical hot paths
- Over-encapsulation (wrapping every field with pass-through getters/setters and no logic) is ceremony without benefit
class BankAccount {
#balance; // Private field
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
withdraw(amount) {
if (amount > 0 && this.#balance >= amount) {
this.#balance -= amount;
return true;
}
return false;
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount(100);
account.deposit(50);
console.log(account.getBalance()); // 150