Strategy — यह क्या है, iOS और Android में स्ट्रैटेजी पैटर्न

लेखक: IT Sectr प्रकाशित: 2026-02-18 पढ़ने का समय: 9 मिनट

Strategy (स्ट्रैटेजी) एक व्यवहारिक डिज़ाइन पैटर्न है जो विनिमेय एल्गोरिदम के एक परिवार को परिभाषित करता है और उनमें से प्रत्येक को एक अलग वर्ग (Strategy) में रखता है। पैटर्न चलते-फिरते एल्गोरिदम चुनने की अनुमति देता है: क्लाइंट कोड एक सामान्य Strategy इंटरफ़ेस के माध्यम से काम करता है, और विशिष्ट कार्यान्वयन रनटाइम पर प्रतिस्थापित किया जाता है। iOS में, पैटर्न को Protocol + स्ट्रैटेजी वर्गों के माध्यम से कार्यान्वित किया जाता है, Android में — Interface + कार्यान्वयन के माध्यम से। Strategy 23 GoF पैटर्न में से एक है, जो भुगतान प्रसंस्करण, सत्यापन, छँटाई और डेटा फ़िल्टरिंग के लिए व्यापक रूप से उपयोग किया जाता है। अधिक जानकारी के लिए — मूल GoF विवरण देखें।

मुख्य बिंदु

  • Strategy — विनिमेय एल्गोरिदम के परिवार के लिए GoF व्यवहारिक पैटर्न
  • एल्गोरिदम का एन्कैप्सुलेशन — प्रत्येक एल्गोरिदम अपने स्वयं के वर्ग में पृथक किया गया है
  • 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 एक एकल क्रिया को वस्तु के रूप में एन्कैप्सुलेट करता है, Strategy विनिमेय एल्गोरिदम के एक सेट को एन्कैप्सुलेट करता है। Command "क्या करना है" (एक execute कॉल), Strategy "कैसे करना है" (कई चरणों का एल्गोरिदम)। Command का उपयोग कतारों, विलंबित निष्पादन, पूर्ववत/पुनः करने के लिए किया जाता है। Strategy का उपयोग रनटाइम पर कार्य करने का तरीका चुनने के लिए किया जाता है। Command को Strategy के साथ पैरामीट्रिज़ किया जा सकता है, दोनों पैटर्न को मिलाकर।

विशेषताStrategyStateCommandTemplate Method
उद्देश्यविनिमेय एल्गोरिदमस्थिति के अनुसार व्यवहारअनुरोध एन्कैप्सुलेशनएल्गोरिदम का ढाँचा
परिवर्तनक्लाइंट द्वारा स्पष्ट रूप सेसंदर्भ द्वारा स्वचालित रूप सेक्लाइंट या कतार द्वाराइनहेरिटेंस द्वारा
स्तरवस्तु (कम्पोज़ीशन)वस्तु (कम्पोज़ीशन)वस्तुवर्ग (इनहेरिटेंस)

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 जाँचों को बहुरूपी सत्यापनकर्ताओं के संग्रह से बदल देता है।

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 पैटर्न का परीक्षण कैसे करें?

प्रत्येक स्ट्रैटेजी का mock निर्भरता के साथ अलग यूनिट परीक्षण द्वारा परीक्षण किया जाता है। संदर्भ का परीक्षण mock स्ट्रैटेजी से किया जाता है — यह सत्यापित करते हुए कि संदर्भ स्ट्रैटेजी विधि को कॉल करता है और सही पैरामीटर पास करता है। 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 — सामान्य इंटरफ़ेस के साथ विनिमेय एल्गोरिदम के लिए व्यवहारिक पैटर्न
  • एन्कैप्सुलेशन — प्रत्येक एल्गोरिदम एक अलग स्ट्रैटेजी वर्ग में पृथक किया गया है
  • iOS Swift — Protocol, संरचनाओं और closures के माध्यम से कार्यान्वयन
  • Android Kotlin — Interface, lambda और Hilt के साथ DI के माध्यम से कार्यान्वयन
  • Open/Closed सिद्धांत — संदर्भ को बदले बिना नई स्ट्रैटेजी जोड़ी जाती हैं
  • अनुप्रयोग — भुगतान, सत्यापन, छँटाई, प्रमाणीकरण, फ़ॉर्मेटिंग

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें