-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathobserver.cpp
More file actions
173 lines (138 loc) · 3.94 KB
/
observer.cpp
File metadata and controls
173 lines (138 loc) · 3.94 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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
Observer design pattern is a behavior design pattern.
In this design pattern, user can define a subscription mechanisiam that
when a certain object have changes, it can notify all the objects that "observing" the certain object.
The typical example is that customer who want to buy the latest iPhone in Appls store.
1. Buyers want to know when the latest type can be reached.
2. They don't want to go to Apple store repeatedly for check.
3. Apple store can save their email or buyers subscribe the news
4. When the latest phone is being sold in Apple store, buyers who are subscribing will be noticed
5. The notification will not be sent to the buyers who did not subscribe.
How to realize?
1. Publisher has to maintain a list for all subscribers.
2. Publisher has method to add/delete subscribers.
3. Publisher has method to notify subscribers
4. When observers receive the notice, they need to do related update.
*/
#include <iostream>
#include <list>
#include <string>
using namespace std;
// subscriber abstract base class
class subscriberBase
{
public:
subscriberBase() = default;
~subscriberBase() {};
// each subscriber should have method 'update'
virtual void update(const string &fromPublisher) = 0;
};
// publisher abstract base class
class pulisherBase
{
public:
pulisherBase() = default;
virtual ~pulisherBase() {};
virtual void add(subscriberBase *subscriber) = 0;
virtual void remove(subscriberBase *subscriber) = 0;
// concrete publisher can notify each subscriber
virtual void notify() = 0;
};
// concrete derived publisher class
class publisher : public pulisherBase
{
public:
~publisher()
{
cout << "Publisher is destroyed, Bye-bye!" << endl;
};
void add(subscriberBase *subscriber) override
{
_subscriberList.push_back(subscriber);
};
void remove(subscriberBase *subscriber) override
{
_subscriberList.remove(subscriber);
};
void notify() override
{
cout << "Current numbers of subscriber is: " << _subscriberList.size() << endl;
for (auto sub : _subscriberList)
{
sub->update(_msg);
}
};
void createMsg(string msgStr)
{
_msg = msgStr;
notify();
};
void someChanges()
{
_msg = "Some change action!";
notify();
};
private:
// publisher should maintained a subscriber list
list<subscriberBase *> _subscriberList;
string _msg;
};
// concrete derived subscriber class
class subscriber : public subscriberBase
{
public:
subscriber(publisher &pub) : _publisher(pub)
{
_publisher.add(this);
cout << "New subscriber is created, its index is: " << ++subscriber::_overallIdx << endl;
_idx = subscriber::_overallIdx;
};
~subscriber()
{
};
void update(const string &fromPublisher) override
{
_msgFromPublisher = fromPublisher;
cout << "A new message for subscriber: " << _idx << ", msg is " << _msgFromPublisher << endl;
};
void removeSubscriber()
{
_publisher.remove(this);
cout << "Removed subscriber index is: " << _idx << endl;
}
private:
string _msgFromPublisher;
publisher &_publisher;
int _idx;
static int _overallIdx;
};
int subscriber::_overallIdx = 0;
void demo()
{
publisher *publish = new publisher;
subscriber *subs1 = new subscriber(*publish);
subscriber *subs2 = new subscriber(*publish);
subscriber *subs3 = new subscriber(*publish);
subscriber *subs4;
subscriber *subs5;
publish->createMsg("Hello, hello, hello.......");
subs3->removeSubscriber();
publish->createMsg("Are you happy??");
subs2->removeSubscriber();
subs4 = new subscriber(*publish);
subs5 = new subscriber(*publish);
publish->createMsg("My car is toyota.......");
subs5->removeSubscriber();
subs4->removeSubscriber();
subs1->removeSubscriber();
delete subs5;
delete subs4;
delete subs3;
delete subs2;
delete subs1;
};
int main()
{
demo();
return 0;
}