> 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-patterns/decorator-design-pattern.md).

# Decorator Design Pattern

ধরো, তুমি এক কফি শপে গেছো। সেখানে সাধারণ এক কাপ কফি পাওয়া যায় ৫০ টাকা দিয়ে। কিন্তু তুমি যদি এক্সট্রা দুধ চাও, তাহলে +২০ টাকা, চকোলেট সিরাপ চাইলে +৩০ টাকা, আর যদি হুইপড ক্রিম চাও, তাহলে +২৫ টাকা যোগ হবে। মূল কফিটার মধ্যে কোনো পরিবর্তন নেই, শুধু কিছু **অপশনাল** জিনিস যোগ হচ্ছে, আর সেটার দামও যুক্ত হচ্ছে।

এটাই হলো **Decorator Design Pattern** এর মূল ধারণা! আমরা একটা বেসিক অবজেক্ট (Basic Coffee) রাখি, তারপর সেটার উপরে বিভিন্ন **ডেকোরেশন** (extra features) অ্যাড করি, কিন্তু মূল অবজেক্ট পরিবর্তন হয় না।

***

### Decorator Design Pattern কী?

Decorator Pattern হলো একটি Structural Design Pattern, যা Inheritance না ব্যবহার করে Composition এর মাধ্যমে এক্সট্রা ফিচার যোগ করার সুযোগ দেয়।

এটি open-closed principle মেনে চলে, মানে আমাদের মূল অবজেক্ট (class) কে না বদলিয়ে নতুন ফিচার যোগ করা যায়।

***

### কখন ব্যবহার করবো?

✅ যখন একটি ক্লাসে নতুন ফিচার যোগ করতে চাই, কিন্তু class modify করতে চাই না।\
✅ যখন multiple feature combinations দরকার হয় (যেমন কফির সাথে দুধ, চকোলেট, ক্রিম ইত্যাদি যেকোনো কম্বিনেশন)।\
✅ যখন runtime এ নতুন behavior যোগ করতে চাই।

***

### উদাহরণ

নীচে কফি শপ উদাহরণ দিয়ে PHP-তে Decorator Pattern কিভাবে কাজ করে, তা দেখানো হলো।

{% code lineNumbers="true" %}

```php
<?php

// Step 1: Base Interface
interface Coffee {
    public function cost();
    public function description();
}

// Step 2: Base Concrete Class
class BasicCoffee implements Coffee {
    public function cost() {
        return 50;
    }
    
    public function description() {
        return "Simple Coffee";
    }
}

// Step 3: Abstract Decorator Class
abstract class CoffeeDecorator implements Coffee {
    protected $coffee;
    
    public function __construct(Coffee $coffee) {
        $this->coffee = $coffee;
    }
    
    public function cost() {
        return $this->coffee->cost();
    }
    
    public function description() {
        return $this->coffee->description();
    }
}

// Step 4: Concrete Decorators
class Milk extends CoffeeDecorator {
    public function cost() {
        return $this->coffee->cost() + 20;
    }
    
    public function description() {
        return $this->coffee->description() . ", Milk";
    }
}

class Chocolate extends CoffeeDecorator {
    public function cost() {
        return $this->coffee->cost() + 30;
    }
    
    public function description() {
        return $this->coffee->description() . ", Chocolate";
    }
}

// Step 5: Usage
$coffee = new BasicCoffee();
echo $coffee->description() . " - " . $coffee->cost() . " Taka\n";

$milkCoffee = new Milk($coffee);
echo $milkCoffee->description() . " - " . $milkCoffee->cost() . " Taka\n";

$chocoMilkCoffee = new Chocolate(new Milk($coffee));
echo $chocoMilkCoffee->description() . " - " . $chocoMilkCoffee->cost() . " Taka\n";

?>
```

{% endcode %}

### Output:

```
Simple Coffee - 50 Taka
Simple Coffee, Milk - 70 Taka
Simple Coffee, Milk, Chocolate - 100 Taka
```

এখানে BasicCoffee ক্লাস পরিবর্তন করা হয়নি, কিন্তু **Milk** এবং **Chocolate** দিয়ে **Decorator Pattern** ব্যবহার করে নতুন ফিচার যোগ করা হয়েছে।

***

### Drawbacks (দুর্বলতা)

❌ যদি অনেক বেশি ডেকোরেটর লাগে, তাহলে Code Complex হয়ে যায়।\
❌ Debugging করতে কিছুটা কঠিন হতে পারে, কারণ multiple wrapper objects তৈরি হয়।\
❌ Dependency Injection ঠিকভাবে না করলে Performance Issue হতে পারে।

***

### 📌 Laravel ও Django-তে Decorator Pattern

#### Laravel: Middleware

Laravel-এ Middleware আসলে Decorator Pattern এর বাস্তব প্রয়োগ। যেমন:

* **AuthenticationMiddleware** ইউজারকে চেক করে লগড ইন কিনা।
* **LoggingMiddleware** প্রতিটি রিকোয়েস্ট লগ করে।
* **CorsMiddleware** ক্রস-ওরিজিন রিকোয়েস্ট হ্যান্ডেল করে।

Laravel-এ **request pipeline** এ Middleware গুলো চেইন আকারে যুক্ত হয়, যেটা **Decorator Pattern** এর মতই কাজ করে।

{% code lineNumbers="true" %}

```php
public function handle($request, Closure $next)
{
    // Custom behavior before request
    $response = $next($request);
    
    // Custom behavior after request
    return $response;
}
```

{% endcode %}

***

#### Django: Middleware

Django-তেও **Middleware** ব্যবহার করে একই কনসেপ্ট ইমপ্লিমেন্ট করা হয়।

{% code lineNumbers="true" %}

```python
class MyMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Custom behavior before request
        response = self.get_response(request)
        # Custom behavior after request
        return response
```

{% endcode %}

এখানে **Middleware Chaining** হয়, যেটা **Decorator Pattern** এর সাথে মিলে যায়।

***

### Summary

| বিষয়                                    | Laravel               | Django                |
| --------------------------------------- | --------------------- | --------------------- |
| **Decorator Pattern কোথায় ব্যবহার হয়?** | Middleware            | Middleware            |
| **কীভাবে কাজ করে?**                     | Request চেইন প্রসেসিং | Request চেইন প্রসেসিং |
| **মূল লক্ষ্য**                          | Request modify করা    | Request modify করা    |
| **Decorator সুবিধা**                    | কোড রিপিটেশন কমানো    | কোড রিপিটেশন কমানো    |

***

Decorator Design Pattern হলো খুবই পাওয়ারফুল এবং flexible প্যাটার্ন। যদি class modify না করে নতুন ফিচার যোগ করতে হয়, তাহলে এটা দারুণ কাজ করে। Laravel ও Django দুটোতেই এটি Middleware আকারে ব্যবহৃত হয়, যা request processing pipeline কে modular করে তোলে।
