Created
April 13, 2021 08:36
-
-
Save jpret/51e8a440e9865837ce6e27e87f7f4b37 to your computer and use it in GitHub Desktop.
Observer design pattern example in C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <memory> | |
| #include <vector> | |
| #include <set> | |
| // Observer from Observer design pattern | |
| template<typename T> | |
| class Observer { | |
| public: | |
| virtual void Notification(const T &event) = 0; | |
| virtual ~Observer() = default; | |
| }; | |
| // Observable from Observer design pattern | |
| template<typename T> | |
| class Observable { | |
| public: | |
| void Notify(const T &event) { | |
| for (auto &observer : observers_) observer->Notification(event); | |
| } | |
| void Subscribe(Observer<T> &observer) { observers_.insert(&observer); } | |
| void Unsubscribe(Observer<T> &observer) { observers_.erase(&observer); } | |
| private: | |
| std::set<Observer<T>*> observers_; | |
| }; | |
| // Pure Abstract / Interface class for service | |
| class Service { | |
| public: | |
| virtual void Run() = 0; | |
| virtual ~Service() = default; | |
| }; | |
| // Concrete class Foo | |
| class FooService : public Service, public Observer<std::string> { | |
| public: | |
| void Run() override { | |
| std::cout << "FooService running..." << std::endl; | |
| } | |
| void Notification(const std::string &event) override { | |
| std::cout << "FooService received event: " << event << std::endl; | |
| }; | |
| }; | |
| // Concrete class Bar | |
| class BarService : public Service, public Observer<std::string> { | |
| public: | |
| void Run() override { | |
| std::cout << "FooService running..." << std::endl; | |
| } | |
| void Notification(const std::string &event) override { | |
| std::cout << "BarService received event: " << event << std::endl; | |
| }; | |
| }; | |
| int main() | |
| { | |
| // Create a string-based event observable | |
| Observable<std::string> message_hub; | |
| // Container for services | |
| std::vector<std::unique_ptr<Service>> services; | |
| // Create services | |
| std::unique_ptr<FooService> foo_service = std::make_unique<FooService>(); | |
| std::unique_ptr<BarService> bar_service = std::make_unique<BarService>(); | |
| // Subscribe for events | |
| message_hub.Subscribe(*foo_service); | |
| message_hub.Subscribe(*bar_service); | |
| // Push services to container | |
| services.push_back(std::move(foo_service)); | |
| services.push_back(std::move(bar_service)); | |
| // Run the services | |
| for(auto &service : services) { | |
| service->Run(); | |
| } | |
| // Push a notification | |
| message_hub.Notify("Services finished..."); | |
| return 0; | |
| } | |
| /* | |
| Console Output: | |
| FooService running... | |
| FooService running... | |
| FooService received event: Services finished... | |
| BarService received event: Services finished... | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment