स्विफ्ट में डिज़ाइन पैटर्न: मूल बातों से व्यवहार तक
\n\nडिज़ाइन पैटर्न (Design Patterns) सामान्य विकास समस्याओं के सिद्ध समाधान हैं। स्विफ्ट और Apple इकोसिस्टम (iOS/macOS) की दुनिया में, रखरखाव योग्य, परीक्षण योग्य और स्केलेबल कोड बनाने के लिए इनका ज्ञान अनिवार्य हो जाता है। इस लेख में, हम प्रमुख पैटर्न को तीन मुख्य श्रेणियों में विभाजित करके समझेंगे: क्रिएशनल, स्ट्रक्चरल और बिहेवियरल। प्रत्येक पैटर्न को स्विफ्ट में एक कार्यशील उदाहरण के साथ समझाया जाएगा।
\n\nक्रिएशनल पैटर्न: सिंगलटन, फ़ैक्टरी मेथड और बिल्डर
\n\nक्रिएशनल पैटर्न ऑब्जेक्ट बनाने की प्रक्रिया को संभालते हैं, इसे अधिक लचीला और क्लाइंट कोड से स्वतंत्र बनाते हैं।
\n\nसिंगलटन (Singleton)
\nयह सुनिश्चित करता है कि एक क्लास का केवल एक इंस्टेंस हो, और उस तक वैश्विक पहुँच प्रदान करता है। iOS में इसका उपयोग अक्सर नेटवर्क सेशन, डेटाबेस (Core Data) या ऐप सेटिंग्स के प्रबंधन के लिए किया जाता है।
\nclass NetworkManager {\n static let shared = NetworkManager()\n private init() {}\n \n func fetchData(from url: URL) {\n // अनुरोध का तर्क\n print("Fetching data from \\(url)")\n }\n}\n\n// उपयोग\nNetworkManager.shared.fetchData(from: URL(string: "https://example.com")!)\n\nफ़ैक्टरी मेथड (Factory Method)
\nयह ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस परिभाषित करता है, लेकिन उपवर्गों को बनाए जाने वाले ऑब्जेक्ट के प्रकार को बदलने की अनुमति देता है। यह iOS संस्करण या कॉन्फ़िगरेशन के आधार पर UI घटक बनाने के लिए उपयुक्त है।
\nprotocol Button {\n func render()\n}\n\nclass iOSButton: Button {\n func render() { print("Rendering iOS button") }\n}\n\nclass macOSButton: Button {\n func render() { print("Rendering macOS button") }\n}\n\nenum Platform { case iOS, macOS }\n\nclass ButtonFactory {\n static func createButton(for platform: Platform) -> Button {\n switch platform {\n case .iOS: return iOSButton()\n case .macOS: return macOSButton()\n }\n }\n}\n\n// उपयोग\nlet button = ButtonFactory.createButton(for: .iOS)\nbutton.render()\n\nबिल्डर (Builder)
\nयह जटिल ऑब्जेक्ट को चरण-दर-चरण बनाने की अनुमति देता है। इसका व्यापक रूप से अनुरोधों (URLRequest) या जटिल UI सेटिंग्स के कॉन्फ़िगरेशन के लिए उपयोग किया जाता है।
\nclass Pizza {\n var dough: String = ""\n var cheese: String = ""\n var toppings: [String] = []\n}\n\nclass PizzaBuilder {\n private var pizza = Pizza()\n \n func setDough(_ dough: String) -> PizzaBuilder {\n pizza.dough = dough\n return self\n }\n \n func setCheese(_ cheese: String) -> PizzaBuilder {\n pizza.cheese = cheese\n return self\n }\n \n func addTopping(_ topping: String) -> PizzaBuilder {\n pizza.toppings.append(topping)\n return self\n }\n \n func build() -> Pizza {\n return pizza\n }\n}\n\n// उपयोग\nlet margherita = PizzaBuilder()\n .setDough("Thin")\n .setCheese("Mozzarella")\n .addTopping("Basil")\n .build()\n\nस्ट्रक्चरल पैटर्न: एडेप्टर, डेकोरेटर और फ़ेसेड
\n\nस्ट्रक्चरल पैटर्न ऑब्जेक्ट और क्लास को बड़ी संरचनाओं में संयोजित करने के तरीकों को परिभाषित करके डिज़ाइन को सरल बनाते हैं।
\n\nएडेप्टर (Adapter)
\nयह असंगत इंटरफ़ेस वाले ऑब्जेक्ट को एक साथ काम करने की अनुमति देता है। क्लासिक उदाहरण तृतीय-पक्ष लाइब्रेरी का एकीकरण या पुराने कोड के साथ काम करना है।
\n// पुराना प्रोटोकॉल\nprotocol OldPaymentSystem {\n func pay(amount: Double)\n}\n\n// नया प्रोटोकॉल\nprotocol NewPaymentSystem {\n func processPayment(amount: Double, currency: String)\n}\n\n// एडेप्टर\nclass PaymentAdapter: NewPaymentSystem {\n private let oldSystem: OldPaymentSystem\n \n init(oldSystem: OldPaymentSystem) {\n self.oldSystem = oldSystem\n }\n \n func processPayment(amount: Double, currency: String) {\n // मुद्रा रूपांतरण\n let convertedAmount = amount * 1.1\n oldSy