-
Notifications
You must be signed in to change notification settings - Fork 0
/
Proxy.cpp
104 lines (101 loc) · 4.22 KB
/
Proxy.cpp
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
//Proxy pattern
#include <iostream>
/**
* Интерфейс Субъекта объявляет общие операции как для Реального Субъекта, так и
* для Заместителя. Пока клиент работает с Реальным Субъектом, используя этот
* интерфейс, вы сможете передать ему заместителя вместо реального субъекта.
*/
class Subject
{
public:
virtual void Request() const = 0;
};
/**
* Реальный Субъект содержит некоторую базовую бизнес-логику. Как правило,
* Реальные Субъекты способны выполнять некоторую полезную работу, которая к
* тому же может быть очень медленной или точной – например, коррекция входных
* данных. Заместитель может решить эти задачи без каких-либо изменений в коде
* Реального Субъекта.
*/
class RealSubject : public Subject
{
public:
void Request() const override
{
std::cout << "RealSubject: Handling request.\n";
}
};
/**
* Интерфейс Заместителя идентичен интерфейсу Реального Субъекта.
*/
class Proxy : public Subject
{
private:
RealSubject *real_subject_;
bool CheckAccess() const
{
// Некоторые реальные проверки должны проходить здесь.
std::cout << "Proxy: Checking access prior to firing a real request.\n";
return true;
}
void LogAccess() const
{
std::cout << "Proxy: Logging the time of request.\n";
}
/**
* Заместитель хранит ссылку на объект класса РеальныйСубъект. Клиент может
* либо лениво загрузить его, либо передать Заместителю.
*/
public:
Proxy(RealSubject *real_subject) : real_subject_(new RealSubject(*real_subject)) {}
~Proxy()
{
delete real_subject_;
}
/**
* Наиболее распространёнными областями применения паттерна Заместитель
* являются ленивая загрузка, кэширование, контроль доступа, ведение журнала и
* т.д. Заместитель может выполнить одну из этих задач, а затем, в зависимости
* от результата, передать выполнение одноимённому методу в связанном объекте
* класса Реального Субъект.
*/
void Request() const override
{
if (this->CheckAccess())
{
this->real_subject_->Request();
this->LogAccess();
}
}
};
/**
* Клиентский код должен работать со всеми объектами (как с реальными, так и
* заместителями) через интерфейс Субъекта, чтобы поддерживать как реальные
* субъекты, так и заместителей. В реальной жизни, однако, клиенты в основном
* работают с реальными субъектами напрямую. В этом случае, для более простой
* реализации паттерна, можно расширить заместителя из класса реального
* субъекта.
*/
void ClientCode(const Subject &subject)
{
// ...
subject.Request();
// ...
}
void test()
{
std::cout << "Client: Executing the client code with a real subject:\n";
RealSubject *real_subject = new RealSubject;
ClientCode(*real_subject);
std::cout << "\n";
std::cout << "Client: Executing the same client code with a proxy:\n";
Proxy *proxy = new Proxy(real_subject);
ClientCode(*proxy);
delete real_subject;
delete proxy;
}
int main()
{
test();
return 0;
}