0
0
LLDsystem_design~7 mins

Encapsulation and information hiding in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
When internal details of a component are exposed, other parts of the system can depend on them directly. This causes bugs when those details change, making the system fragile and hard to maintain.
Solution
Encapsulation bundles data and methods that operate on that data within a single unit, like a class. Information hiding restricts access to internal details, exposing only what is necessary through a controlled interface. This protects the internal state and reduces unintended dependencies.
Architecture
Client
Code
Encapsulated

This diagram shows a client interacting only with the public methods of an encapsulated component, while internal details remain hidden and protected.

Trade-offs
✓ Pros
Reduces system fragility by preventing external code from depending on internal details.
Improves maintainability by allowing internal changes without affecting clients.
Enhances security by controlling access to sensitive data.
Simplifies debugging by localizing effects of changes.
✗ Cons
May introduce slight overhead due to access control methods.
Requires careful design to decide what to expose and what to hide.
Can lead to more boilerplate code for getters/setters if overused.
Always use in object-oriented design, especially when building components or modules that will be reused or maintained by multiple developers.
In very simple scripts or prototypes where speed of development is more important than maintainability and the codebase is small and short-lived.
Real World Examples
Amazon
Amazon uses encapsulation in their microservices to hide internal database schemas and expose only APIs, allowing independent service evolution without breaking clients.
Netflix
Netflix encapsulates streaming session management details within services, exposing only necessary controls to clients, enabling seamless updates without user disruption.
Uber
Uber encapsulates driver location tracking logic inside services, hiding complex algorithms and data structures from other parts of the system.
Code Example
The before code allows direct access to the balance, which can be set to invalid values. The after code hides the balance attribute by making it private and exposes controlled methods to modify it safely, preventing invalid states.
LLD
### Before (no encapsulation, direct access)
class BankAccount:
    def __init__(self, balance):
        self.balance = balance

account = BankAccount(100)
account.balance = -50  # Invalid state allowed


### After (encapsulation and information hiding)
class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # Private attribute

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount

    def get_balance(self):
        return self.__balance

account = BankAccount(100)
account.deposit(50)
account.withdraw(30)
print(account.get_balance())  # Outputs: 120
account.__balance = -50  # Has no effect on actual balance
OutputSuccess
Alternatives
Modularization
Modularization groups related functionality into separate modules but does not necessarily hide internal details within those modules.
Use when: When you want to organize code into logical units but do not need strict access control.
Service-Oriented Architecture (SOA)
SOA encapsulates functionality as services with well-defined interfaces but at a higher system level rather than within code units.
Use when: When designing distributed systems requiring loose coupling between large components.
Summary
Encapsulation bundles data and behavior into a single unit and controls access to internal details.
Information hiding protects internal state by exposing only necessary interfaces, reducing dependencies.
Together, they improve maintainability, reduce bugs, and make systems easier to evolve.