Skip to content

Commit 3534216

Browse files
Eder DuranEder Duran
authored andcommitted
Observer design pattern
1 parent ef3dcd7 commit 3534216

File tree

2 files changed

+221
-0
lines changed

2 files changed

+221
-0
lines changed

src/Observer/Conceptual/Output.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Hi, I'm the Observer "1".
2+
Hi, I'm the Observer "2".
3+
Hi, I'm the Observer "3".
4+
There are 3 observers in the list.
5+
Observer "1": a new message is available --> Hello World! :D
6+
Observer "2": a new message is available --> Hello World! :D
7+
Observer "3": a new message is available --> Hello World! :D
8+
Observer "3" removed from the list.
9+
There are 2 observers in the list.
10+
Observer "1": a new message is available --> The weather is hot today! :p
11+
Observer "2": a new message is available --> The weather is hot today! :p
12+
Hi, I'm the Observer "4".
13+
Observer "2" removed from the list.
14+
Hi, I'm the Observer "5".
15+
There are 3 observers in the list.
16+
Observer "1": a new message is available --> My new car is great! ;)
17+
Observer "4": a new message is available --> My new car is great! ;)
18+
Observer "5": a new message is available --> My new car is great! ;)
19+
Observer "5" removed from the list.
20+
Observer "4" removed from the list.
21+
Observer "1" removed from the list.
22+
Goodbye, I was the Observer "5".
23+
Goodbye, I was the Observer "4".
24+
Goodbye, I was the Observer "3".
25+
Goodbye, I was the Observer "2".
26+
Goodbye, I was the Observer "1".
27+
Goodbye, I was the Subject.

src/Observer/Conceptual/main.cc

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/**
2+
* EN: Observer Design Pattern
3+
*
4+
* Intent: Lets you define a subscription mechanism to notify multiple objects
5+
* about any events that happen to the object they're observing.
6+
*
7+
* Note that there's a lot of different terms with similar meaning associated
8+
* with this pattern. Just remember that the Subject is also called the
9+
* Publisher and the Observer is often called the Subscriber and vice versa.
10+
* Also the verbs "observe", "listen" or "track" usually mean the same thing.
11+
*
12+
* RU: Паттерн Наблюдатель
13+
*
14+
* Назначение: Создаёт механизм подписки, позволяющий одним объектам следить и
15+
* реагировать на события, происходящие в других объектах.
16+
*
17+
* Обратите внимание, что существует множество различных терминов с похожими
18+
* значениями, связанных с этим паттерном. Просто помните, что Субъекта также
19+
* называют Издателем, а Наблюдателя часто называют Подписчиком и наоборот.
20+
* Также глаголы «наблюдать», «слушать» или «отслеживать» обычно означают одно и
21+
* то же.
22+
*/
23+
24+
#include <list>
25+
#include <string>
26+
#include <iostream>
27+
28+
class IObserver
29+
{
30+
31+
public:
32+
virtual ~IObserver(){};
33+
virtual void Update(const std::string &message_from_subject) = 0;
34+
};
35+
36+
class ISubject
37+
{
38+
public:
39+
virtual ~ISubject(){};
40+
virtual void Attach(IObserver *observer) = 0;
41+
virtual void Detach(IObserver *observer) = 0;
42+
virtual void Notify() = 0;
43+
};
44+
45+
/**
46+
* EN: The Subject owns some important state and notifies observers when the
47+
* state changes.
48+
*
49+
* RU: Издатель владеет некоторым важным состоянием и оповещает наблюдателей о
50+
* его изменениях.
51+
*/
52+
53+
class Subject : public ISubject
54+
{
55+
56+
public:
57+
virtual ~Subject()
58+
{
59+
std::cout << "Goodbye, I was the Subject.\n";
60+
}
61+
62+
/**
63+
* EN: The subscription management methods.
64+
*
65+
* RU: Методы управления подпиской.
66+
*/
67+
void Attach(IObserver *observer) override
68+
{
69+
list_observer_.push_back(observer);
70+
}
71+
void Detach(IObserver *observer) override
72+
{
73+
list_observer_.remove(observer);
74+
}
75+
void Notify() override
76+
{
77+
std::list<IObserver *>::iterator iterator = list_observer_.begin();
78+
HowManyObserver();
79+
while (iterator != list_observer_.end())
80+
{
81+
(*iterator)->Update(message_);
82+
++iterator;
83+
}
84+
}
85+
86+
void CreateMessage(std::string message = "Empty")
87+
{
88+
this->message_ = message;
89+
Notify();
90+
}
91+
void HowManyObserver()
92+
{
93+
std::cout << "There are " << list_observer_.size() << " observers in the list.\n";
94+
}
95+
96+
/**
97+
* EN: Usually, the subscription logic is only a fraction of what a Subject
98+
* can really do. Subjects commonly hold some important business logic, that
99+
* triggers a notification method whenever something important is about to
100+
* happen (or after it).
101+
*
102+
* RU: Обычно логика подписки – только часть того, что делает Издатель.
103+
* Издатели часто содержат некоторую важную бизнес-логику, которая запускает
104+
* метод уведомления всякий раз, когда должно произойти что-то важное (или
105+
* после этого).
106+
*/
107+
void SomeBusinessLogic()
108+
{
109+
this->message_ = "change message message";
110+
Notify();
111+
std::cout << "I'm about to do some thing important\n";
112+
}
113+
114+
private:
115+
std::list<IObserver *> list_observer_;
116+
std::string message_;
117+
};
118+
119+
class Observer : public IObserver
120+
{
121+
122+
public:
123+
Observer(Subject &subject) : subject_(subject)
124+
{
125+
this->subject_.Attach(this);
126+
std::cout << "Hi, I'm the Observer \"" << ++Observer::static_number_ << "\".\n";
127+
this->number_ = Observer::static_number_;
128+
}
129+
virtual ~Observer()
130+
{
131+
std::cout << "Goodbye, I was the Observer \"" << this->number_ << "\".\n";
132+
}
133+
134+
void Update(const std::string &message_from_subject) override
135+
{
136+
message_from_subject_ = message_from_subject;
137+
PrintInfo();
138+
}
139+
void RemoveMeFromTheList()
140+
{
141+
subject_.Detach(this);
142+
std::cout << "Observer \"" << number_ << "\" removed from the list.\n";
143+
}
144+
void PrintInfo()
145+
{
146+
std::cout << "Observer \"" << this->number_ << "\": a new message is available --> " << this->message_from_subject_ << "\n";
147+
}
148+
149+
private:
150+
std::string message_from_subject_;
151+
Subject &subject_;
152+
static int static_number_;
153+
int number_;
154+
};
155+
156+
int Observer::static_number_ = 0;
157+
158+
void ClientCode()
159+
{
160+
Subject *subject = new Subject;
161+
Observer *observer1 = new Observer(*subject);
162+
Observer *observer2 = new Observer(*subject);
163+
Observer *observer3 = new Observer(*subject);
164+
Observer *observer4;
165+
Observer *observer5;
166+
167+
subject->CreateMessage("Hello World! :D");
168+
observer3->RemoveMeFromTheList();
169+
170+
subject->CreateMessage("The weather is hot today! :p");
171+
observer4 = new Observer(*subject);
172+
173+
observer2->RemoveMeFromTheList();
174+
observer5 = new Observer(*subject);
175+
176+
subject->CreateMessage("My new car is great! ;)");
177+
observer5->RemoveMeFromTheList();
178+
179+
observer4->RemoveMeFromTheList();
180+
observer1->RemoveMeFromTheList();
181+
182+
delete observer5;
183+
delete observer4;
184+
delete observer3;
185+
delete observer2;
186+
delete observer1;
187+
delete subject;
188+
}
189+
190+
int main()
191+
{
192+
ClientCode();
193+
return 0;
194+
}

0 commit comments

Comments
 (0)