代理模式

代理最好的体现是 Nginx 的反向代理功能,将客户端本该直接发给服务器 Server 的请求数据由自己接受之后转发给服务器 Server ,再把服务器 Server 本该直接返回给客户端的响应数据由自己接受之后转发给客户端。

nginx.png

没错,本该可以直接被服务器 Server 完成的事情,Nginx 代理服务器提前做了(尽管这样说是不正确的,因为 Nginx 只是单纯的把服务器 Server 的接受和转发功能给做了,但是其它服务器 Server 的功能并没有做)。我们可以这样说,Nginx 代理服务器和 服务器 Server 由共同之处,可以抽象出一个基类 HTTPServer。

好的,我们的 Nginx 类就得包含 Server 对象了,这样就可以调用 Server 提供的接口,让 Nginx 对外提供服务,尽管这些工作实际上还是由 Server 自己完成,而给外界的假象就是 Nginx 来完成的。

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
#include <iostream>

class HTTPServer {
public:
virtual void Request() const = 0;
};

class Server : public HTTPServer {
public:
void Request() const override {
std::cout << "RealSubject: Handling request.\n";
}
};

class Proxy : public HTTPServer {
private:
Server* 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(Server* real_subject) : real_subject_(new Server(*real_subject)) {
}

~Proxy() {
delete real_subject_;
}
void Request() const override {
if (this->CheckAccess()) {
this->real_subject_->Request();
this->LogAccess();
}
}
};

void ClientCode(const HTTPServer& subject) {
subject.Request();
}

int main() {
std::cout << "Client: Executing the client code with a real subject:\n";
Server* real_subject = new Server;
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;
return 0;
}

输出结果:

1
2
3
4
5
6
7
Client: Executing the client code with a real subject:
RealSubject: Handling request.

Client: Executing the same client code with a proxy:
Proxy: Checking access prior to firing a real request.
RealSubject: Handling request.
Proxy: Logging the time of request.

我想,我们可以绘制出 UML 类图:

代理模式.png