C++ में Event Bus और Observer पैटर्न: सिद्धांत से आधुनिक कार्यान्वयन तक
C++ में आधुनिक विकास में, अक्सर उन घटकों के बीच संदेश आदान-प्रदान के लिए एक लचीली प्रणाली की आवश्यकता होती है जो एक-दूसरे के बारे में सीधे नहीं जानते हैं। Observer पैटर्न और इसका विकास — Event Bus — इस समस्या को हल करता है, जिससे शिथिल रूप से जुड़ी, विस्तार योग्य प्रणालियाँ बनाना संभव होता है। इस लेख में, हम मानक लाइब्रेरी (C++17/20) का उपयोग करके C++ में Event Bus को लागू करने का तरीका समझेंगे, और व्यावहारिक उदाहरण देखेंगे।
Observer पैटर्न: शास्त्रीय आधार
Observer पैटर्न वस्तुओं के बीच "एक-से-अनेक" संबंध को परिभाषित करता है: जब एक वस्तु (विषय) अपनी स्थिति बदलती है, तो सभी आश्रित वस्तुएँ (प्रेक्षक) स्वचालित रूप से इसके बारे में सूचित हो जाती हैं। C++ में शास्त्रीय कार्यान्वयन इस प्रकार दिखता है:
#include <iostream>#include <vector>#include <memory>#include <algorithm>
// प्रेक्षक का आधार वर्गclass IObserver {public: virtual ~IObserver() = default; virtual void update(const std::string& message) = 0;};
// विषय (प्रकाशक)class Subject {private: std::vector<std::weak_ptr<IObserver>> observers_;public: void attach(std::shared_ptr<IObserver> observer) { observers_.push_back(observer); }
void detach(std::shared_ptr<IObserver> observer) { observers_.erase( std::remove_if(observers_.begin(), observers_.end(), [&observer](const std::weak_ptr<IObserver>& wp) { auto sp = wp.lock(); return !sp || sp == observer; }), observers_.end() ); }
void notify(const std::string& message) { for (auto it = observers_.begin(); it != observers_.end(); ) { if (auto sp = it->lock()) { sp->update(message); ++it; } else { it = observers_.erase(it); // "मृत" संदर्भ हटाएँ } } }};
// ठोस प्रेक्षकclass ConcreteObserver : public IObserver {private: std::string name_;public: ConcreteObserver(const std::string& name) : name_(name) {} void update(const std::string& message) override { std::cout << "[" << name_ << "] प्राप्त: " << message << std::endl; }};
int main() { auto subject = std::make_shared<Subject>(); auto obs1 = std::make_shared<ConcreteObserver>("प्रेक्षक 1"); auto obs2 = std::make_shared<ConcreteObserver>("प्रेक्षक 2");
subject->attach(obs1); subject->attach(obs2); subject->notify("घटना घटित हुई!");
subject->detach(obs1); subject->notify("केवल दूसरे के लिए");
return 0;}यह कोड काम करता है, लेकिन इसकी सीमाएँ हैं: सभी प्रेक्षकों को IObserver से विरासत प्राप्त करनी होगी, और संदेश स्ट्रिंग होने चाहिए। व्यवहार में, अधिक लचीली प्रणाली की आवश्यकता होती है।
Event Bus: आधुनिक विकास
Event Bus एक केंद्रीकृत बस है जिसके माध्यम से घटक घटनाओं को प्रकाशित कर सकते हैं और उनकी सदस्यता ले सकते हैं। शास्त्रीय Observer से मुख्य अंतर:
- टाइप की गई घटनाएँ — प्रत्येक घटना का अपना डेटा प्रकार होता है।
- कठोर पदानुक्रम का अभाव — सदस्यों को सामान्य इंटरफ़ेस से विरासत प्राप्त करने की आवश्यकता नहीं है।
- वैश्विक या स्थानीय बस — पूरे एप्लिकेशन के लिए एक Event Bus या कई पृथक बसें हो सकती हैं।
C++17/20 में std::any के साथ Event Bus का कार्यान्वयन
किसी भी प्रकार के डेटा को संग्रहीत करने के लिए std::any और हैंडलर के लिए std::function का उपयोग करें। घटनाओं को प्रकार के अनुसार अलग करने के लिए std::type_index लागू करें।
#include <iostream>#include <any>#include <function