Event-driven आर्किटेक्चर Kotlin में: यह सिर्फ एक फैशनेबल ट्रेंड क्यों नहीं है
\nकल्पना करें कि आपका एप्लिकेशन एक पूरी तरह से समायोजित मशीन है। हर गियर जानता है कि कब घूमना है, हर पिस्टन जानता है कि कब चलना है। लेकिन क्या होगा अगर एक दिन पूरी मशीन को रोके बिना एक नया पार्ट जोड़ने की ज़रूरत पड़े? पारंपरिक सिंक्रोनस आर्किटेक्चर में, यह अक्सर एक दुःस्वप्न बन जाता है: पूरे मॉड्यूल को फिर से लिखना, अनंत कॉल चेन का परीक्षण करना और नींद हराम रातें।
\nयहाँ पर Kotlin में event-driven आर्किटेक्चर मंच पर आता है — एक प्रतिमान जहाँ घटक सीधे कॉल के बजाय इवेंट के माध्यम से संवाद करते हैं। Kotlin, अपने कोरूटीन और रिएक्टिव स्ट्रीम के साथ, इसके लिए बिल्कुल आदर्श उपकरण प्रदान करता है। इस लेख में, हम सिर्फ सिद्धांत के बारे में बात नहीं करेंगे — हम वास्तविक कोड लिखेंगे, Kotlin Flow और Channels का विश्लेषण करेंगे, और मैं दिखाऊंगा कि एक लचीली, स्केलेबल सिस्टम कैसे बनाया जाए जो पहले लोड पर बिखर न जाए।
\n\nइवेंट-ओरिएंटेड आर्किटेक्चर सरल शब्दों में क्या है
\nशास्त्रीय दृष्टिकोण में (कल्पना करें माइक्रोसर्विसेज जो REST के माध्यम से एक-दूसरे को कॉल करते हैं), हर अनुरोध एक कठोर संबंध है। सर्विस A सर्विस B को कॉल करता है, जवाब का इंतजार करता है, और अगर B डाउन हो जाता है — सब कुछ टूट जाता है। Event-driven आर्किटेक्चर में यह अलग है: घटक इवेंट प्रकाशित करते हैं (जैसे, "ऑर्डर बनाया गया") और उनकी सदस्यता लेते हैं। कोई किसी का इंतजार नहीं करता, कोई सीधे किसी को कॉल नहीं करता।
\nKotlin की खूबसूरती यह है कि यह इस मॉडल को मूल रूप से लागू करने की अनुमति देता है, बिना भारी फ्रेमवर्क जोड़े। कोरूटीन हल्के थ्रेड प्रदान करते हैं, और Channel और Flow इवेंट के लिए तैयार बसें हैं।
\nआइए सबसे सरल उदाहरण देखें — Kotlin पर अपना खुद का EventBus:
\n\nimport kotlinx.coroutines.*\nimport kotlinx.coroutines.channels.*\n\nclass SimpleEventBus {\n private val events = Channel<Any>(Channel.UNLIMITED)\n\n suspend fun publish(event: Any) {\n events.send(event)\n }\n\n suspend fun subscribe(handler: suspend (Any) -> Unit) {\n for (event in events) {\n handler(event)\n }\n }\n}\n\n// उपयोग\nfun main() = runBlocking {\n val bus = SimpleEventBus()\n \n launch {\n bus.subscribe { event ->\n println("इवेंट प्राप्त हुआ: $event")\n }\n }\n \n delay(100)\n bus.publish("Hello, Event-Driven!")\n delay(100)\n}\n\nयह कोड आधार है। हम एक चैनल बनाते हैं जो एक एसिंक्रोनस कतार की तरह काम करता है। प्रकाशक इवेंट डालता है, सब्सक्राइबर इसे लेता है। सब कुछ सरल है, लेकिन यहाँ पहले से ही Kotlin में event-driven आर्किटेक्चर की ताकत दिखती है: सब्सक्राइबर और प्रकाशक एक-दूसरे के बारे में कुछ नहीं जानते।
\n\nKotlin Flow: इवेंट के लिए रिएक्टिव स्ट्रीम
\nChannel अच्छा है, लेकिन वास्तविक प्रोजेक्ट के लिए अक्सर और अधिक की आवश्यकता होती है: कोल्ड और हॉट स्ट्रीम, ट्रांसफॉर्मेशन, एरर हैंडलिंग। यहाँ Kotlin Flow खेल में आता है — एक रिएक्टिव लाइब्रेरी जो सीधे भाषा में बनी है।
\nFlow Kotlin में एसिंक्रोनस प्रोग्रामिंग के लिए आदर्श है, जब इवेंट लगातार उत्पन्न होते हैं। उदाहरण के लिए, मुद्रा दर अपडेट, समाचार फ़ीड या UI स्थिति।
\n\nकोल्ड बनाम हॉट स्ट्रीम
\nअंतर को समझना महत्वपूर्ण है:
\n- \n
- कोल्ड स्ट्रीम (Cold Stream) — केवल तब काम करना शुरू करता है जब कोई उसकी सदस्यता लेता है। प्रत्येक सब्सक्राइबर को डेटा का अपना स्ट्रीम मिलता है। \n
- हॉट स्ट्रीम (Hot Stream) — सब्सक्राइबर से स्वतंत्र रूप से लगातार काम करता है। देर से आने वाले सब्सक्राइबर पुराने इवेंट को खो देते हैं। \n
Event-driven आर्किटेक्चर के लिए आमतौर पर हॉट स्ट्रीम की आवश्यकता होती है। Kotlin में, इन्हें SharedFlow या StateFlow के माध्यम से लागू किया जाता है।
उदाहरण — एक नोटिफिकेशन सिस्टम:
\n\nimport kotlinx.coroutines.*\nimport kotlinx.coroutines.flow.*\n\ndata class Notification(val userId: String, val message: String)\n\nclass NotificationService {\n private val _notifications = MutableSharedF