-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObserver.cpp
More file actions
108 lines (92 loc) · 2.45 KB
/
Observer.cpp
File metadata and controls
108 lines (92 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/**
* @cite Observer Pattern states that in order to notify components about some event that occurs in the system, then the components should observe the event and be able to handle them as well.
* Aims at promoting flexibility and maintainablity by decoupling the observer and observable.
*
* @brief Observer Pattern can be exemplified by NewsLetter class that sends out newsletters to its subscribers.
* How to only notify the people that are subscribed about the new newsletter?
* How to provide people with the unsubscribe functionality ?
*/
#include <iostream>
#include <set>
#include <string>
// Forward Declaration of Observer
template <typename>
class Observer;
/**
* @brief Template Abstraction for Observable
*/
template <typename T>
class Observable
{
protected:
// Keeps track of all the subscribers
std::set<Observer<T> *> observers;
public:
// Notifes all the subscribers
void notify(T &source, std::string news)
{
for (auto observer : observers)
observer->news(source, news);
}
// Allows Person to subscribe
void subscribe(Observer<T> &sub)
{
observers.insert(&sub);
}
// Allows Person to unsubscribe
void unsubscribe(Observer<T> &unsub)
{
observers.erase(&unsub);
}
};
/**
* @brief NewsLetter that Person can subscribe to and recieve news.
*/
class NewsLetter : public Observable<NewsLetter>
{
public:
// Publish new news to subscribers
void new_news(std::string news)
{
notify(*this, news);
}
};
/**
* @brief Template Abstractions for Observers
*/
template <typename T>
class Observer
{
public:
// Observes the new news that is published.
virtual void news(T &source, std::string new_news) = 0;
};
/**
* @brief Person that can subsrcibe to the NewsLetter.
*/
class Person : public Observer<NewsLetter>
{
std::string name;
public:
Person(std::string name) : name(name) {}
// Receive new news from the subscribed NewsLetter.
void news(NewsLetter &source, std::string new_news) override
{
std::cout << "News Recieved by " << name << " :: " << new_news << std::endl;
}
};
int main()
{
Person jon{"Jon"};
Person jane{"Jane"};
NewsLetter nl;
nl.subscribe(jane);
nl.new_news("Lost Dog !!!");
std::cout << std::endl;
nl.subscribe(jon);
nl.new_news("Found Dog !!!");
std::cout << std::endl;
nl.unsubscribe(jane);
nl.new_news("Lost Dog Again !!!");
return 0;
}