एक ही सिक्के के दो पहलू: Swift में फंक्शनल बनाम ऑब्जेक्ट-ओरिएंटेड दृष्टिकोण
\n\nजब मैंने iOS के लिए कोडिंग शुरू की थी, तो मुझे लगता था कि ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग ही एकमात्र सही रास्ता है। क्लास, इनहेरिटेंस, पॉलीमॉर्फिज़्म - ये सब एक डेवलपर के लिए पवित्र ग्रंथ की तरह लगते थे। लेकिन फिर मैंने Swift में फंक्शनल प्रोग्रामिंग की खोज की, और दुनिया बदल गई। पता चला कि कोड ऐसा लिखा जा सकता है जो स्थिति को बदलता नहीं है, जिसका परीक्षण करना आसान है और जो गणितीय सूत्र जैसा दिखता है।
\n\nSwift एक अनोखी भाषा है। यह बहु-प्रतिमान है। इसका मतलब है कि आप एक ही प्रोजेक्ट में OOP और फंक्शनल दृष्टिकोण को मिला सकते हैं, दोनों दुनिया का सर्वश्रेष्ठ ले सकते हैं। लेकिन भ्रमित कैसे न हों? क्लास का उपयोग कब करें, और क्लोजर और map का कब? आइए समझते हैं।
\n\nऑब्जेक्ट-ओरिएंटेड Swift: क्लासिक जो काम करता है
\n\nऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग (OOP) Swift में क्लास, प्रोटोकॉल और इनहेरिटेंस के आसपास बनता है। यह एक प्रतिमान है जहाँ डेटा और व्यवहार एक साथ रहते हैं। आप एक मॉडल बनाते हैं - उदाहरण के लिए, "उपयोगकर्ता" - और यह ऑब्जेक्ट स्वयं जानता है कि कैसे परिचय देना है, नाम कैसे बदलना है या उम्र की गणना कैसे करनी है।
\n\nयहाँ Swift में एक क्लासिक उदाहरण है:
\n\nclass User {\n var name: String\n var age: Int\n \n init(name: String, age: Int) {\n self.name = name\n self.age = age\n }\n \n func greet() -> String {\n return "नमस्ते, मेरा नाम \\(name) है और मैं \\(age) वर्ष का हूँ।"\n }\n \n func haveBirthday() {\n age += 1\n }\n}\n\nlet user = User(name: "अन्ना", age: 25)\nuser.haveBirthday()\nprint(user.greet()) // नमस्ते, मेरा नाम अन्ना है और मैं 26 वर्ष का हूँ।\n\nइस कोड में हम Swift में ऑब्जेक्ट-ओरिएंटेड दृष्टिकोण का उपयोग कर रहे हैं। हमारे पास स्थिति (गुण name, age) है जो बदल सकती है (विधि haveBirthday)। यह सहज रूप से समझ में आता है, खासकर यदि आप Java या C++ से आए हैं। लेकिन एक बारीक बात है: परिवर्तनीय स्थिति बग का स्रोत है। जितने अधिक ऑब्जेक्ट एक-दूसरे को बदलते हैं, प्रोग्राम को डीबग करना उतना ही कठिन होता है।
\n\nफंक्शनल Swift: क्लोजर और अपरिवर्तनीयता की शक्ति
\n\nSwift में फंक्शनल प्रोग्रामिंग एक अलग दृष्टिकोण प्रस्तुत करती है। यहाँ फंक्शन "प्रथम श्रेणी के नागरिक" हैं। आप उन्हें पैरामीटर के रूप में पास कर सकते हैं, अन्य फंक्शन से लौटा सकते हैं और वेरिएबल में स्टोर कर सकते हैं। मुख्य सिद्धांत शुद्ध फंक्शन (pure functions) हैं, जो बाहरी स्थिति को नहीं बदलते हैं और समान इनपुट के लिए हमेशा समान परिणाम लौटाते हैं।
\n\nआइए देखें कि वही उदाहरण फंक्शनल शैली में कैसा दिखता है:
\n\nstruct User {\n let name: String\n let age: Int\n}\n\nfunc greet(user: User) -> String {\n return "नमस्ते, मेरा नाम \\(user.name) है और मैं \\(user.age) वर्ष का हूँ।"\n}\n\nfunc haveBirthday(user: User) -> User {\n return User(name: user.name, age: user.age + 1)\n}\n\nlet user = User(name: "अन्ना", age: 25)\nlet olderUser = haveBirthday(user: user)\nprint(greet(user: olderUser)) // नमस्ते, मेरा नाम अन्ना है और मैं 26 वर्ष का हूँ।\n\nध्यान दें: हम क्लास के बजाय स्ट्रक्चर (struct) का उपयोग कर रहे हैं। Swift में स्ट्रक्चर value types हैं। असाइन करने पर वे कॉपी हो जाते हैं। फंक्शन haveBirthday मूल ऑब्जेक्ट को नहीं बदलता, बल्कि एक नया बनाता है। यह फंक्शनल दृष्टिकोण का मुख्य विचार है - अपरिवर्तनीयता (immutability)।
दृष्टिकोणों की तुलना: कब क्या उपयोग करें?
\n\nअब आइए ईमानदारी से Swift में OOP और फंक्शनल प्रोग्रामिंग की तुलना करें। प्रत्येक की अपनी ताकत है।
\n\nSwift में ऑब्जेक्ट-ओरिएंटेड दृष्टिकोण
\n\n- \n
- लाभ: वास्तविक दुनिया के मॉडलिंग के लिए सहज रूप से समझ में आता है। UI-घटकों (UIViewController, UIView) के लिए उत्कृष्ट है। इनहेरिटेंस कोड के पुन: उपयोग को सरल बनाता है। \n
- नुकसान: परिवर्तनशीलता