Strategy — یہ کیا ہے، iOS اور Android میں اسٹریٹیجی پیٹرن

مصنف: IT Sectr اشاعت: 2026-02-18 مطالعے کا وقت: 9 منٹ

Strategy (اسٹریٹیجی) ایک رویاتی ڈیزائن پیٹرن ہے جو قابل تبادلہ الگورتھم کے ایک خاندان کی تعریف کرتا ہے اور ان میں سے ہر ایک کو علیحدہ کلاس (Strategy) میں رکھتا ہے۔ پیٹرن چلتے پھرتے الگورتھم منتخب کرنے کی اجازت دیتا ہے: کلائنٹ کوڈ ایک مشترکہ Strategy انٹرفیس کے ذریعے کام کرتا ہے، اور مخصوص نفاذ رن ٹائم میں تبدیل کیا جاتا ہے۔ iOS میں، پیٹرن کو Protocol + اسٹریٹیجی کلاسز کے ذریعے نافذ کیا جاتا ہے، Android میں — Interface + نفاذ کے ذریعے۔ Strategy 23 GoF پیٹرنز میں سے ایک ہے، جو ادائیگی کی پروسیسنگ، توثیق، ترتیب اور ڈیٹا فلٹرنگ کے لیے وسیع پیمانے پر استعمال ہوتا ہے۔ مزید تفصیل کے لیے — اصل GoF تفصیل دیکھیں۔

اہم نکات

  • Strategy — قابل تبادلہ الگورتھم کے خاندان کے لیے GoF رویاتی پیٹرن
  • الگورتھم کی encapsulation — ہر الگورتھم اپنی کلاس میں الگ تھلگ ہے
  • Strategy انٹرفیس — ایک مشترکہ معاہدہ جسے تمام ٹھوس اسٹریٹیجی نافذ کرتی ہیں
  • وراثت کے بجائے ترکیب — سیاق و متن اسٹریٹیجی کا حوالہ رکھتا ہے، رویہ وراثت میں نہیں لیتا
  • Open/Closed اصول — موجودہ کوڈ کو تبدیل کیے بغیر نئی اسٹریٹیجی شامل کی جا سکتی ہیں

Strategy پیٹرن کیا ہے: جوہر اور ساخت

Strategy 23 GoF (Gang of Four) پیٹرنز میں سے ایک ہے، جو "Design Patterns: Elements of Reusable Object-Oriented Software" (1994) کتاب میں بیان کیا گیا ہے۔ پیٹرن رن ٹائم پر الگورتھم منتخب کرنے کا مسئلہ حل کرتا ہے۔ متعدد شرطی بیانات (if-else, switch) والی ایک کلاس لکھنے کے بجائے، Strategy ہر الگورتھم کو ایک مشترکہ انٹرفیس کے ساتھ علیحدہ کلاس میں نکالنے کی تجویز کرتا ہے۔ سیاق و متن (وہ کلاس جو اسٹریٹیجی استعمال کرتی ہے) Strategy انٹرفیس کا حوالہ رکھتا ہے اور عملدرآمد ٹھوس اسٹریٹیجی کو سونپتا ہے۔

پیٹرن کی ساخت میں تین عناصر شامل ہیں: Context (سیاق و متن) Strategy کا حوالہ رکھتا ہے اور اس کا طریقہ کال کرتا ہے؛ Strategy (انٹرفیس) تمام الگورتھم کے لیے ایک مشترکہ طریقہ اعلان کرتا ہے؛ ConcreteStrategy (ٹھوس اسٹریٹیجی) انٹرفیس کو نافذ کرتی ہے اور ٹھوس الگورتھم رکھتی ہے۔ کلائنٹ مطلوبہ اسٹریٹیجی بناتا ہے اور اسے کنسٹرکٹر، سیٹر یا طریقہ پیرامیٹر کے ذریعے سیاق و متن میں دیتا ہے۔ سیاق و متن نہیں جانتا کہ کون سی مخصوص اسٹریٹیجی عمل میں ہے — یہ صرف انٹرفیس کے ساتھ کام کرتا ہے۔

جزوکردارمثال
ContextStrategy کا حوالہ رکھتا ہےPaymentProcessor, Sorter
Strategyالگورتھم کے لیے مشترکہ انٹرفیسProtocol PaymentStrategy
ConcreteStrategyالگورتھم کا ٹھوس نفاذCardPayment, PayPalPayment

Open/Closed اصول — Strategy کا بنیادی فائدہ۔ نظام توسیع کے لیے کھلا ہے (نئی اسٹریٹیجی شامل کی جا سکتی ہے) اور ترمیم کے لیے بند ہے (سیاق و متن کوڈ کو تبدیل کرنے کی ضرورت نہیں)۔ پیٹرن کے بغیر، نیا الگورتھم شامل کرنے کے لیے موجودہ کلاس کو تبدیل کرنا ضروری ہے، جو OCP کی خلاف ورزی کرتا ہے اور رجعت کی خرابیوں کا خطرہ بڑھاتا ہے۔ Strategy کلاس کے سائز کو بھی کم کرتا ہے: switch-case والی 200 سطروں والی کلاس کی بجائے، آپ کو 20 سطروں والی 6 کلاسیں ملتی ہیں۔

iOS میں Strategy: Protocol کے ساتھ Swift میں نفاذ

Swift میں Strategy کو Protocol (اسٹریٹیجی انٹرفیس) اور اسٹریٹیجی کلاسز یا ڈھانچوں کے ذریعے نافذ کیا جاتا ہے۔ Swift پروٹوکول متعلقہ اقسام اور عام رکاوٹوں کو سپورٹ کرتے ہیں، جو اسٹریٹیجی ڈیزائن کرتے وقت لچک فراہم کرتے ہیں۔ سیاق و متن عام طور پر ایک ViewModel کلاس یا سروس ہے جو init میں یا خاصیت کے ذریعے اسٹریٹیجی قبول کرتی ہے۔ پیٹرن iOS منصوبوں میں واقعہ ہینڈلنگ، اینیمیشن، ڈیٹا فارمیٹنگ اور UI اسٹریٹیجی کے لیے وسیع پیمانے پر استعمال ہوتا ہے۔

swift
// 1. Protocol Strategy
protocol PaymentStrategy {
    func pay(amount: Decimal) async throws -> PaymentResult
}

// 2. Concrete Strategies
struct CardPaymentStrategy: PaymentStrategy {
    let cardNumber: String
    let cvv: String

    func pay(amount: Decimal) async throws -> PaymentResult {
        // بینکنگ API کو درخواست بھیجنا
        return PaymentResult(status: .success, transactionId: "tx_\(UUID())")
    }
}

struct PayPalPaymentStrategy: PaymentStrategy {
    let email: String

    func pay(amount: Decimal) async throws -> PaymentResult {
        // PayPal SDK پر ری ڈائریکٹ
        return PaymentResult(status: .success, transactionId: "pp_\(UUID())")
    }
}

// 3. Context
class PaymentProcessor {
    private var strategy: PaymentStrategy

    init(strategy: PaymentStrategy) {
        self.strategy = strategy
    }

    func setStrategy(_: PaymentStrategy) {
        strategy = strategy
    }

    func processPayment(amount: Decimal) async throws -> PaymentResult {
        return try await strategy.pay(amount: amount)
    }
}

// استعمال
let processor = PaymentProcessor(strategy: CardPaymentStrategy(cardNumber: "4111...", cvv: "123"))
let result = try await processor.processPayment(amount: 99.99)

SwiftUI میں Strategy — پیٹرن قدرتی طور پر MVVM کے ساتھ ضم ہوتا ہے۔ ViewModel میں ایک اسٹریٹیجی خاصیت ہوتی ہے اور صارف کے عمل پر اس کا طریقہ کال کرتا ہے۔ SwiftUI View @Published یا @State کے ذریعے ڈیٹا حاصل کرتی ہے — اسٹریٹیجی View سے نفاذ کی تفصیلات چھپاتی ہے۔ مثال کے طور پر، ٹیکسٹ توثیق اسٹریٹیجی (emailValidator, phoneValidator) ان پٹ فیلڈ کی قسم کے مطابق تبدیل کی جاتی ہے۔ Strategy کو SwiftUI کے ساتھ ملا کر UIKit سے وراثت حاصل کیے بغیر لچک ملتی ہے۔

Android میں Strategy: Interface کے ساتھ Kotlin میں نفاذ

Kotlin میں Strategy زبان کی سطح پر Interface استعمال کرتا ہے اور آسانی کے لیے فنکشنل انٹرفیس (SAM) استعمال کرتا ہے۔ Kotlin lambda کو سپورٹ کرتا ہے، جس سے علیحدہ اسٹریٹیجی کلاس اعلان کیے بغیر الگورتھم کو فنکشن کے طور پر منتقل کیا جا سکتا ہے۔ Android میں، پیٹرن ViewModel اور Use Cases میں ڈیٹا لوڈنگ، کیشنگ اور خرابی سے نمٹنے کے الگورتھم کو الگ کرنے کے لیے استعمال ہوتا ہے۔ Clean Architecture استعمال کرنے والے Android منصوبے جھنڈوں (mock, real, cache) کے مطابق مختلف ذخیرہ نفاذ انجیکٹ کرنے کے لیے Strategy استعمال کرتے ہیں۔

kotlin
// 1. Interface Strategy
interface PaymentStrategy {
    suspend fun pay(amount: BigDecimal): PaymentResult
}

// 2. Concrete Strategies
class CardPaymentStrategy(
    private val cardNumber: String,
    private val cvv: String
) : PaymentStrategy {
    override suspend fun pay(amount: BigDecimal): PaymentResult {
        // Retrofit کے ذریعے بینکنگ API
        return PaymentResult(success = true, transactionId = "tx_${UUID.randomUUID()}")
    }
}

class PayPalPaymentStrategy(
    private val email: String
) : PaymentStrategy {
    override suspend fun pay(amount: BigDecimal): PaymentResult {
        // PayPal SDK انضمام
        return PaymentResult(success = true, transactionId = "pp_${UUID.randomUUID()}")
    }
}

// 3. Context
class PaymentProcessor(
    private val strategy: PaymentStrategy
) {
    fun setStrategy(strategy: PaymentStrategy): PaymentProcessor {
        return PaymentProcessor(strategy)
    }

    suspend fun processPayment(amount: BigDecimal): PaymentResult {
        return strategy.pay(amount)
    }
}

// ViewModel میں استعمال
class CheckoutViewModel : ViewModel() {
    private var processor = PaymentProcessor(CardPaymentStrategy("4111...", "123"))

    fun payWithCard() {
        viewModelScope.launch {
            val result = processor.processPayment(BigDecimal("99.99"))
            // نتیجہ کی پروسیسنگ
        }
    }
}

Hilt/Dagger کے ساتھ Strategy — Android منصوبوں میں، اسٹریٹیجی اکثر DI کے ذریعے انجیکٹ کی جاتی ہیں۔ Hilt @Binds یا @Provides کے ذریعے PaymentStrategy کا ٹھوس نفاذ فراہم کرتا ہے۔ یہ سیاق و متن کوڈ کو تبدیل کیے بغیر اسٹریٹیجی تبدیل کرنے کی اجازت دیتا ہے — دوسرے بلڈ (debug/release) کے لیے صرف DI ماڈیول تبدیل کریں۔ مثال کے طور پر، ڈیبگنگ کے لیے MockPaymentStrategy انجیکٹ کیا جاتا ہے، پروڈکشن کے لیے اصلی بینکنگ اسٹریٹیجی۔ Strategy + DI کا امتزاج زیادہ سے زیادہ لچک فراہم کرتا ہے۔

State، Command اور Template Method کے ساتھ Strategy کا موازنہ

Strategy vs State — ساختی طور پر پیٹرن ایک جیسے ہیں: دونوں ایک انٹرفیس اور ٹھوس کلاسز کے ساتھ ترکیب استعمال کرتے ہیں۔ فرق مقصد میں ہے: Strategy ایک آزاد الگورتھم منتخب کرتا ہے، State اپنی حالت کے مطابق آبجیکٹ کے رویے کو کنٹرول کرتا ہے۔ State میں، سیاق و متن خود اسٹریٹیجی تبدیل کرتا ہے جب حالت بدلتی ہے؛ Strategy میں، سیاق و متن تبدیلی کو کنٹرول نہیں کرتا — کلائنٹ واضح طور پر الگورتھم سیٹ کرتا ہے۔ اسٹریٹیجی ایک دوسرے کے بارے میں نہیں جانتیں، جبکہ حالتیں ایک دوسرے میں منتقل ہو سکتی ہیں۔

Strategy vs Command — Command ایک ایکشن کو آبجیکٹ کے طور پر encapsulate کرتا ہے، Strategy قابل تبادلہ الگورتھم کے ایک سیٹ کو encapsulate کرتا ہے۔ Command "کیا کرنا ہے" (ایک execute کال)، Strategy "کیسے کرنا ہے" (کئی مراحل کا الگورتھم)۔ Command قطاروں، موخر عملدرآمد، کالعدم/دوبارہ کرنے کے لیے استعمال ہوتا ہے۔ Strategy رن ٹائم پر کام انجام دینے کا طریقہ منتخب کرنے کے لیے استعمال ہوتا ہے۔ کمانڈز کو Strategy کے ساتھ پیرامیٹرائز کیا جا سکتا ہے، دونوں پیٹرن کو ملا کر۔

خصوصیتStrategyStateCommandTemplate Method
مقصدقابل تبادلہ الگورتھمحالت کے مطابق رویہدرخواست encapsulationالگورتھم کا ڈھانچہ
تبدیلیکلائنٹ کے ذریعے واضح طور پرسیاق و متن کے ذریعے خودکارکلائنٹ یا قطاروراثت سے
سطحآبجیکٹ (ترکیب)آبجیکٹ (ترکیب)آبجیکٹکلاس (وراثت)

Strategy vs Template Method — دونوں پیٹرن الگورتھم کی تعریف کرتے ہیں لیکن مختلف طریقوں سے۔ Template Method وراثت استعمال کرتا ہے: ایک بنیادی کلاس الگورتھم کا ڈھانچہ (ٹیمپلیٹ طریقہ) طے کرتی ہے، ذیلی کلاسیں انفرادی مراحل کو اوور رائڈ کرتی ہیں۔ Strategy ترکیب استعمال کرتا ہے: الگورتھم مکمل طور پر علیحدہ کلاس میں خارجی کیا جاتا ہے۔ Template Method مقررہ الگورتھم ساخت والے معاملات کے لیے آسان ہے، Strategy — جب الگورتھم مکمل طور پر مختلف ہوں اور متحرک طور پر تبدیل ہو سکیں۔

Strategy پیٹرن کے استعمال کی حقیقی مثالیں

ادائیگی کی پروسیسنگ — Strategy کی کلاسک مثال۔ آن لائن اسٹور کی شاپنگ کارٹ میں اشیاء کی فہرست ہوتی ہے اور ادائیگی کا طریقہ صارف منتخب کرتا ہے۔ ہر طریقہ (کارڈ، PayPal، Apple Pay، Google Pay، کرپٹو کرنسی) مشترکہ pay(amount) دستخط کے ساتھ ایک علیحدہ اسٹریٹیجی ہے۔ PaymentProcessor سیاق و متن نہیں جانتا کہ ادائیگی کیسے پروسیس ہوتی ہے — یہ مشترکہ طریقہ کال کرتا ہے۔ نیا ادائیگی طریقہ شامل کرنے کے لیے کارٹ کوڈ تبدیل کرنے کی ضرورت نہیں۔

ڈیٹا کی توثیق — Strategy اسی فیلڈ کے مختلف توثیق کے اصولوں کے لیے استعمال ہوتا ہے۔ EmailValidatorStrategy، PhoneValidatorStrategy، AgeValidatorStrategy validate(input) طریقہ کے ساتھ مشترکہ ValidationStrategy انٹرفیس نافذ کرتی ہیں۔ رجسٹریشن فارم ہر فیلڈ کو جانچنے کے لیے اسٹریٹیجی کا ایک سیٹ استعمال کرتا ہے۔ توثیق کی اسٹریٹیجی کو ایک زنجیر (Chain of Responsibility) میں ملایا جا سکتا ہے یا ایک لوپ میں ایک ساتھ لاگو کیا جا سکتا ہے۔ یہ لمبی if-else جانچوں کو polymorphic توثیق کنندگان کے مجموعے سے بدل دیتا ہے۔

swift
// ترتیب کی اسٹریٹیجی
protocol SortingStrategy {
    func sort<T>(_ items: [T]) -> [T] where T: Comparable
}

struct QuickSortStrategy: SortingStrategy {
    func sort<T>(_ items: [T]) -> [T] { /* quicksort */ items }
}

struct MergeSortStrategy: SortingStrategy {
    func sort<T>(_ items: [T]) -> [T] { /* mergesort */ items }
}

class SortedDataSource<T> {
    private var strategy: SortingStrategy
    func display(_ items: [T]) { let sorted = strategy.sort(items) }
}

مصدقہ — موبائل ایپس میں، فراہم کنندہ کے مطابق مصدقہ اسٹریٹیجی تبدیل ہوتی ہیں۔ AuthStrategy login()، logout()، getToken() طریقوں کے ساتھ EmailPasswordAuth، GoogleAuth، AppleAuth، BiometricAuth کے لیے نافذ کیا جاتا ہے۔ AuthManager سیاق و متن DI یا فیکٹری کے ذریعے اسٹریٹیجی قبول کرتا ہے۔ یہ لاگ ان اسکرین کو تبدیل کیے بغیر نئے مصدقہ فراہم کنندگان شامل کرنے کی اجازت دیتا ہے۔ Strategy پیٹرن بہت سی OAuth لائبریریوں اور Firebase Authentication کی بنیاد ہے۔

اکثر پوچھے گئے سوالات

if-else کی بجائے Strategy کب استعمال کریں؟

Strategy درست ہے جب آپ کے پاس 3+ الگورتھم ہوں جو تبدیل یا پھیل سکتے ہیں۔ اگر 2 الگورتھم ہیں اور وہ مستحکم ہیں — سادہ if-else کم خرچ ہے۔ Strategy استعمال کریں جب الگورتھم ایپلیکیشن کے مختلف حصوں میں استعمال ہوں، جب آپ کو رن ٹائم پر الگورتھم تبدیل کرنے کی ضرورت ہو، یا جب ہر الگورتھم کو اپنی انحصار اور ٹیسٹ کی ضرورت ہو۔

کیا Strategy اور State ایک ہی ہیں؟

نہیں، یہ مختلف پیٹرن ہیں جن کی ساخت ایک جیسی ہے۔ Strategy — کلائنٹ واضح طور پر الگورتھم منتخب کرتا ہے اور اسٹریٹیجی آزاد ہیں۔ State — جب اس کی داخلی حالت بدلتی ہے تو آبجیکٹ خود اپنا رویہ بدلتا ہے اور حالتیں ایک دوسرے میں منتقل ہو سکتی ہیں۔ State میں، سیاق و متن حالت کی تبدیلی کا انتظام کرتا ہے؛ Strategy میں، کلائنٹ کوڈ یہ کرتا ہے۔

کیا Strategy کلاسوں کے بغیر — closures کے ذریعے استعمال کیا جا سکتا ہے؟

ہاں، Swift اور Kotlin میں اسٹریٹیجی کو closure یا lambda کے طور پر منتقل کیا جا سکتا ہے۔ Swift: typealias PaymentHandler = (Decimal) async throws -> PaymentResult. Kotlin: typealias PaymentFun = suspend (BigDecimal) -> PaymentResult. یہ سادہ معاملات کے لیے کوڈ آسان بناتا ہے لیکن نام بندی اور دستاویزات کھو دیتا ہے۔ 1-2 الگورتھم کے لیے، closure کافی ہے؛ 4+ کے لیے، علیحدہ کلاسیں بہتر ہیں۔

Strategy پیٹرن کی جانچ کیسے کریں؟

ہر اسٹریٹیجی کو فرضی انحصار کے ساتھ علیحدہ یونٹ ٹیسٹ سے جانچا جاتا ہے۔ سیاق و متن کو فرضی اسٹریٹیجی سے جانچا جاتا ہے — تصدیق کرتے ہوئے کہ سیاق و متن اسٹریٹیجی کا طریقہ کال کرتا ہے اور صحیح پیرامیٹر منتقل کرتا ہے۔ Swift میں، فرضی کے لیے XCTest + پروٹوکول استعمال کریں؛ Kotlin میں، MockK یا Mockito استعمال کریں۔ بنیادی فائدہ: ہر اسٹریٹیجی پیچیدہ سیٹ اپ کے بغیر الگ تھلگ جانچی جاتی ہے۔

کیا Strategy ایک GoF پیٹرن ہے؟

ہاں، Strategy ان 23 پیٹرنز میں سے ایک ہے جو "Design Patterns: Elements of Reusable Object-Oriented Software" (Gamma, Helm, Johnson, Vlissides, 1994) کتاب میں بیان کیے گئے ہیں۔ یہ رویاتی پیٹرن کے گروپ سے تعلق رکھتا ہے۔ متبادل نام: Policy۔ Smalltalk-80 میں اصل مثال کوڈ GoF کے اصل ایڈیشن میں دستیاب ہے۔

خلاصہ

  • Strategy — مشترکہ انٹرفیس کے ساتھ قابل تبادلہ الگورتھم کے لیے رویاتی پیٹرن
  • Encapsulation — ہر الگورتھم علیحدہ اسٹریٹیجی کلاس میں الگ تھلگ
  • iOS Swift — Protocol، ڈھانچوں اور closures کے ذریعے نفاذ
  • Android Kotlin — Interface، lambda اور Hilt کے ساتھ DI کے ذریعے نفاذ
  • Open/Closed اصول — سیاق و متن کو تبدیل کیے بغیر نئی اسٹریٹیجی شامل کی جاتی ہیں
  • استعمال — ادائیگیاں، توثیق، ترتیب، مصدقہ، فارمیٹنگ

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں