> For the complete documentation index, see [llms.txt](https://mominur.gitbook.io/mominur-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mominur.gitbook.io/mominur-notes/system-design/design-principles/encapsulation.md).

# Encapsulation

ধরুন, আপনি একটি মোবাইল ব্যবহার করছেন। ভেতরে কত চিপ, কত circuit, কত complex calculation হচ্ছে সেটা আপনাকে জানতে হচ্ছে না। আপনার শুধু দরকার screen, button আর কিছু feature ব্যবহার করা। ভেতরের data আর logic গুলো সুন্দরভাবে cover করে আপনাকে সহজ interface দেওয়া হয়েছে।

এই ভেতরের details লুকিয়ে বাইরে থেকে কেবল দরকারি অংশ অ্যাক্সেস করতে দেওয়া— একে বলা হয় **Encapsulation**

***

### Encapsulation কী?

**Encapsulation** হলো একটি **Object-Oriented Programming (OOP)** Principle, যেখানে **data (variables)** এবং সেই data-র উপর কাজ করা **methods (functions)** একসাথে একটি Class এর ভেতরে বেঁধে ফেলা হয়।

সহজভাবে বললে:

* **Encapsulation** = Data + Methods → একসাথে একটি capsule এর ভেতরে রাখা।

***

### কেন Encapsulation দরকার?

1. **Data Security:** Class এর ভেতরের sensitive data বাইরে থেকে সরাসরি change করা যায় না।
2. **Control:** কিভাবে data read/write হবে সেটা developer নিয়ন্ত্রণ করতে পারে।
3. **Maintainability:** কোড clean এবং সহজে maintain করা যায়।
4. **Flexibility:** data access করতে চাইলে developer method এর মাধ্যমে logic যোগ করতে পারে (যেমন validation)।

***

### Example

{% code lineNumbers="true" %}

```php
<?php
class BankAccount {
    // Properties (Encapsulated Data)
    private $balance;

    // Constructor
    public function __construct($initialBalance) {
        $this->balance = $initialBalance;
    }

    // Getter Method (read balance)
    public function getBalance() {
        return $this->balance;
    }

    // Setter Method (deposit money)
    public function deposit($amount) {
        if ($amount > 0) {
            $this->balance += $amount;
        } else {
            echo "Invalid deposit amount.";
        }
    }

    // Setter Method (withdraw money)
    public function withdraw($amount) {
        if ($amount > 0 && $amount <= $this->balance) {
            $this->balance -= $amount;
        } else {
            echo "Invalid or insufficient balance.";
        }
    }
}

// ব্যবহার
$account = new BankAccount(500);  // Initial balance = 500
$account->deposit(200);           // Deposit 200
$account->withdraw(100);          // Withdraw 100

echo "Current Balance: " . $account->getBalance();
?>
```

{% endcode %}

এখানে `balance` property **private** করে দেওয়া হয়েছে। অর্থাৎ বাইরে থেকে `$account->balance` সরাসরি change করা যাবে না। কেবলমাত্র `deposit()` এবং `withdraw()` method এর মাধ্যমে balance পরিবর্তন করা যাবে। এটাই হলো **Encapsulation** এর beauty।

***

### Encapsulation বাস্তবায়নের উপায়

#### 1. **Access Modifiers ব্যবহার করে (public, private, protected)**

এটাই সবচেয়ে সরাসরি উপায়।

* **public:** Class এর বাইরে থেকেও সরাসরি access করা যায়।
* **private:** কেবলমাত্র সেই Class এর ভেতরে access করা যাবে।
* **protected:** Class এবং তার child Class এর ভেতরে access করা যাবে।

{% code lineNumbers="true" %}

```php
class User {
    public $name;         // সবার জন্য খোলা
    private $password;    // বাইরে থেকে inaccessible
    protected $email;     // কেবল Class বা subclass এ accessible
}
```

{% endcode %}

***

#### 2. **Getters এবং Setters (Controlled Access)**

Sensitive data কে **private** করে বাইরে থেকে সরাসরি access বন্ধ করে দেওয়া হয়। পরিবর্তে **getter/setter method** এর মাধ্যমে controlled access দেওয়া হয়।

{% code lineNumbers="true" %}

```php
class User {
    private $password;

    public function setPassword($pass) {
        if(strlen($pass) >= 6) {
            $this->password = $pass;
        } else {
            echo "Password must be at least 6 characters.";
        }
    }

    public function getPassword() {
        return str_repeat("*", strlen($this->password)); // Masked
    }
}

$user = new User();
$user->setPassword("secret123");
echo $user->getPassword(); // Output: *********
```

{% endcode %}

এখানে বাইরে থেকে password সরাসরি change করা যাচ্ছে না, বরং `setPassword()` method ব্যবহার করতে হচ্ছে।

***

#### 3. **Constructor এর মাধ্যমে Initialization**

Encapsulation enforce করার আরেকটা উপায় হলো sensitive property-গুলো **constructor এর মাধ্যমে initialize** করা। এতে অবজেক্ট তৈরি করার সময় সঠিক data validation enforce করা যায়।

{% code lineNumbers="true" %}

```php
class Product {
    private $price;

    public function __construct($price) {
        if ($price > 0) {
            $this->price = $price;
        } else {
            throw new Exception("Invalid price!");
        }
    }

    public function getPrice() {
        return $this->price;
    }
}
```

{% endcode %}

***

#### 4. **Encapsulation with Inheritance (protected members)**

Encapsulation শুধু data লুকানোর জন্য নয়, inheritance এর মাধ্যমে controlled exposure দেওয়ার জন্যও ব্যবহার হয়।

{% code lineNumbers="true" %}

```php
class Vehicle {
    protected $speed = 0;

    public function accelerate($value) {
        $this->speed += $value;
    }
}

class Car extends Vehicle {
    public function getSpeed() {
        return $this->speed;
    }
}

$car = new Car();
$car->accelerate(50);
echo $car->getSpeed(); // 50
```

{% endcode %}

এখানে `speed` property বাইরে থেকে সরাসরি access করা যাবে না, কিন্তু child class ব্যবহার করতে পারছে।

***

#### 5. **Encapsulation via Interface (Indirect)**

Interface এর মাধ্যমেও আমরা নির্দিষ্ট method enforce করতে পারি, যাতে data access কেবল নির্দিষ্ট method দিয়েই হয়।

{% code lineNumbers="true" %}

```php
interface AccountInterface {
    public function deposit($amount);
    public function withdraw($amount);
}

class BankAccount implements AccountInterface {
    private $balance = 0;

    public function deposit($amount) {
        $this->balance += $amount;
    }

    public function withdraw($amount) {
        if ($amount <= $this->balance) {
            $this->balance -= $amount;
        }
    }

    public function getBalance() {
        return $this->balance;
    }
}
```

{% endcode %}

এখানে account balance বাইরে থেকে সরাসরি change করা যাচ্ছে না। কেবলমাত্র interface methods দিয়েই control করা যাবে।
