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

# Strategy Design Pattern

যদি আপনার প্রজেক্টে **একই কাজের জন্য একাধিক অপশন থাকে** এবং আপনি চান নির্দিষ্ট পরিস্থিতিতে বিভিন্ন অপশন ব্যবহার করতে, তাহলে Strategy Pattern ব্যবহার করা উচিত।&#x20;

উদাহরণস্বরূপ:

1. **Database Selection:**
   * আজ MySQL ব্যবহার করছেন, কিন্তু ভবিষ্যতে PostgreSQL, Oracle, বা MongoDB ব্যবহার করতে হতে পারে।
   * যদি একাধিক ডাটাবেজ Support  করাতে চান, তাহলে Strategy Pattern ব্যবহার করে ডাটাবেজের অপশনগুলো আলাদা ক্লাসে রাখতে পারবেন।
2. **Authentication System:**
   * আপনার অ্যাপে OAuth, JWT, বা API Key authentication ব্যবহার করা লাগতে পারে।
   * যদি চাই যে ভবিষ্যতে নতুন authentication method সহজে যোগ করতে পারি, তাহলে Strategy Pattern উপযোগী হবে।
3. **Caching Mechanism:**
   * Redis, Memcached বা Local File System-এর মাধ্যমে caching করা যেতে পারে।
   * নির্দিষ্ট কন্ডিশনের ভিত্তিতে কোন ক্যাশিং ব্যবহার করা হবে, তা নির্ধারণ করতে Strategy Pattern সহায়ক।
4. **Payment Gateway Integration:**
   * Stripe, PayPal, Google Pay ইত্যাদি পেমেন্ট অপশন ব্যবহার করা হতে পারে।
   * আপনি চাইলে Strategy Pattern ব্যবহার করে runtime-এ পেমেন্ট গেটওয়ে পরিবর্তন করতে পারেন।
5. **Sorting Algorithms:**
   * যদি অ্যাপে একাধিক Sorting Algorithm (Bubble Sort, Quick Sort, Merge Sort) প্রয়োজন হয় এবং নির্দিষ্ট পরিস্থিতিতে নির্দিষ্ট অ্যালগরিদম প্রয়োগ করতে হয়, তাহলে Strategy Pattern ব্যবহার করা ভালো হবে।

### **কেন ব্যবহার করবেন?**

1. **Flexible & Extensible:** নতুন স্ট্র্যাটেজি সহজেই যোগ করা যায়।
2. **Code Reusability:** একবার ইমপ্লিমেন্ট করলে বারবার ব্যবহার করা যায়।
3. **Runtime Decision Making:** প্রয়োজন অনুযায়ী আলাদা স্ট্র্যাটেজি ব্যবহার করা যায়।
4. **Better Code Maintainability:** বিভিন্ন লজিক আলাদা রাখা যায়, কোড পড়তে ও পরিবর্তন করতে সহজ হয়।

যেখানে একই কাজের জন্য একাধিক অপশন থাক&#x9C7;**,** এবং অপশন পরিবর্তনযোগ্য রাখা প্রয়োজন, সেখানে **Strategy Pattern** ব্যবহার করা বেস্ট!&#x20;

### Example

John একজন সফটওয়্যার ইঞ্জিনিয়ার, যিনি XYZ নামে একটি ই-কমার্স কোম্পানিতে কাজ করেন। শুরুতে XYZ-এ শুধুমাত্র PayPal পেমেন্ট ছিল, এবং সবকিছু বেশ ভালোই চলছিল। তার কোড ছিল খুবই সাধারণ:

{% code lineNumbers="true" %}

```php
class PaymentProcessor {
    public function pay($amount, $method) {
        if ($method == "paypal") {
            echo "Processing payment of $$amount using PayPal.";
        }
    }
}
```

{% endcode %}

কিন্তু সমস্যা শুরু হলো, যখন কোম্পানি নতুন **Credit Card** এবং **Bank Transfer** পেমেন্ট যোগ করল।

{% code lineNumbers="true" %}

```php
class PaymentProcessor {
    public function pay($amount, $method) {
        if ($method == "paypal") {
            echo "Processing payment of $$amount using PayPal.";
        } elseif ($method == "credit_card") {
            echo "Processing payment of $$amount using Credit Card.";
        } elseif ($method == "bank_transfer") {
            echo "Processing payment of $$amount using Bank Transfer.";
        }
    }
}
```

{% endcode %}

#### **এখন সমস্যা কী?**

❌ অনেক বেশি if-else চেকিং – প্রতিবার নতুন পেমেন্ট মেথড যোগ করলে কোড পরিবর্তন করতে হচ্ছে।\
❌ ভবিষ্যতে Maintenance কঠিন হবে – ৫-৬ টা পেমেন্ট মেথড হলে কোড গুলিয়ে যাবে!\
❌ Open/Closed Principle ভঙ্গ হচ্ছে – নতুন কিছু যোগ করতে গেলে পুরনো কোড পরিবর্তন করতে হচ্ছে।

একদিন **CTO** John-কে ডেকে বললেন:

> **CTO:** আমরা Cryptocurrency পেমেন্ট যোগ করতে চাই, এবং ভবিষ্যতে আরো নতুন পেমেন্ট মেথড আসবে। এটা কিভাবে সহজে হ্যান্ডেল করব?
>
> **John:** আমরা **Strategy Pattern** ব্যবহার করতে পারি! প্রতিটি পেমেন্ট মেথড আলাদা **Strategy Class** হবে, এবং আমরা Runtime-এ পেমেন্ট মেথড পরিবর্তন করতে পারব।"
>
> **CTO:** দারুণ! তাহলে কাজ শুরু করো।

### Strategy Pattern ইমপ্লিমেন্টেশন For Payment

#### **Step 1:** Payment Strategy Interface **তৈরি করা**

প্রতিটি পেমেন্ট মেথড এই ইন্টারফেস অনুসরণ করবে।

{% code lineNumbers="true" %}

```php
interface PaymentStrategy {
    public function pay($amount);
}
```

{% endcode %}

#### Step 2: আলাদা আলাদা Payment Strategy তৈরি করা

**PayPal Payment Class**

{% code lineNumbers="true" %}

```php
class PayPalPayment implements PaymentStrategy {
    public function pay($amount) {
        echo "Processing $$amount using PayPal.";
    }
}
```

{% endcode %}

**Credit Card Payment Class**

{% code lineNumbers="true" %}

```php
class CreditCardPayment implements PaymentStrategy {
    public function pay($amount) {
        echo "Processing $$amount using Credit Card.";
    }
}
```

{% endcode %}

**Bank Transfer Payment Class**

{% code lineNumbers="true" %}

```php
class BankTransferPayment implements PaymentStrategy {
    public function pay($amount) {
        echo "Processing $$amount using Bank Transfer.";
    }
}
```

{% endcode %}

#### Step 3: [Context Class](#user-content-fn-1)[^1] তৈরি করা

{% code lineNumbers="true" %}

```php
class PaymentContext {
    private PaymentStrategy $strategy;

    public function setPaymentStrategy(PaymentStrategy $strategy) {
        $this->strategy = $strategy;
    }

    public function payAmount($amount) {
        $this->strategy->pay($amount);
    }
}
```

{% endcode %}

#### Step 4: Client Code (Dynamic Payment Selection)

{% code lineNumbers="true" %}

```php
$context = new PaymentContext();

// PayPal দিয়ে পেমেন্ট করা
$context->setPaymentStrategy(new PayPalPayment());
$context->payAmount(100);

// Credit Card দিয়ে পেমেন্ট করা
$context->setPaymentStrategy(new CreditCardPayment());
$context->payAmount(200);

// Bank Transfer দিয়ে পেমেন্ট করা
$context->setPaymentStrategy(new BankTransferPayment());
$context->payAmount(300);
```

{% endcode %}

### Strategy Pattern-এর লাভ কী?

✅ **Dynamic Payment Switching** – পেমেন্ট অপশন সহজেই বদলানো যায়।\
✅ **No More If-Else Mess!** – বিশাল if-else structure এড়ানো যায়।\
✅ **Easy to Extend** – নতুন পেমেন্ট মেথড যোগ করতে চাইলে আলাদা **Strategy Class** লিখলেই হবে!\
✅ **Better Code Maintenance** – পেমেন্ট লজিক আর মেইন কোডের মধ্যে কোনো ডিপেন্ডেন্সি নেই।

XYZ এখন **PayPal, Credit Card, Bank Transfer** সবকিছুই সাপোর্ট করে, এবং ভবিষ্যতে আরও নতুন পেমেন্ট মেথড খুব সহজে যোগ করা যাবে।

**CTO John-কে ডেকে বললেন:**

> তুমি **Strategy Pattern** ব্যবহার করে আমাদের Payment System-কে **Flexible এবং Maintainable** করেছো। গ্রেট জব!

John হাসল। ভালো **Design Pattern** মানেই সহজ **Scalability এবং Maintenance**!

### Where Laravel , Django and most framework Uses the Strategy Pattern

<table><thead><tr><th width="143.66668701171875">Feature</th><th>Strategy Implemented</th></tr></thead><tbody><tr><td><strong>Database</strong></td><td>Dynamically choose database (<code>MySQL</code>, <code>PostgreSQL</code>, <code>SQLite</code>, <code>Oracle</code>)</td></tr><tr><td><strong>Authentication</strong> </td><td>Supports multiple authentication mechanisms (<code>session</code>, <code>jwt</code>, <code>api</code>)</td></tr><tr><td><strong>Caching</strong></td><td>Supports various cache backends (<code>file-based</code>, <code>database</code>, <code>redis</code>, <code>memcached</code>)</td></tr><tr><td><strong>Queue</strong></td><td>Supports different queue systems (<code>database</code>, <code>redis</code>, <code>sqs</code>)</td></tr><tr><td><strong>Logging</strong></td><td>Supports different logging channels (<code>single</code>, <code>daily</code>, <code>slack</code>)</td></tr><tr><td><strong>Storage</strong> </td><td>Supports multiple file storage backends (<code>LocalStorage</code>, <code>S3</code>, <code>Google Cloud Storage</code>).</td></tr></tbody></table>

[^1]: * এটি হলো **main class**, যেটি **client (user code)** এর সাথে যোগাযোগ করে।
    * Context নিজে অ্যালগরিদম জানে না, বরং একটি **strategy/state object ধরে রাখে**।
    * Context সেই object কে ব্যবহার করে কাজ করায়।
