目录
代理模式(Proxy Pattern)
代理模式是一种结构型设计模式,它提供了一个代理对象,充当了被访问对象的接口,使得客户端可以通过代理对象间接访问被访问对象。代理模式可以用于控制对被访问对象的访问,以及在访问被访问对象前后执行一些额外的操作。
实际应用
虚拟代理
假设有一个复杂的图片加载器,加载图片可能会耗费大量时间和内存,这个时候我们可以使用虚拟代理来延迟图片的加载,只有当图片真正需要显示时才进行加载。
#include <iostream>
#include <string>
#include <memory>
// 图片接口
class Image {
public:
virtual void display() = 0;
};
// 具体实现:图片加载器
class RealImage : public Image {
private:
std::string filename;
public:
RealImage(const std::string& filename) : filename(filename) {
loadFromDisk();
}
void display() override {
std::cout << "Displaying image: " << filename << "\n";
}
void loadFromDisk() {
std::cout << "Loading image: " << filename << "\n";
}
};
// 代理类:虚拟代理
class ImageProxy : public Image {
private:
std::string filename;
std::shared_ptr<RealImage> realImage;
public:
ImageProxy(const std::string& filename) : filename(filename), realImage(nullptr) {}
void display() override {
if (!realImage) {
realImage = std::make_shared<RealImage>(filename);
}
realImage->display();
}
};
int main() {
std::shared_ptr<Image> image = std::make_shared<ImageProxy>("example.jpg");
// 图片加载延迟到需要显示时
image->display();
// 第二次显示时不会重新加载图片
image->display();
return 0;
}
远程代理
假设有一个远程服务,客户端通过网络与该服务通信,这时候可以使用远程代理来隐藏网络通信的细节,并提供一个与本地对象相同的接口。
#include <iostream>
#include <string>
// 服务接口
class RemoteService {
public:
virtual void request(const std::string& data) = 0;
};
// 具体实现:远程服务
class ConcreteRemoteService : public RemoteService {
public:
void request(const std::string& data) override {
std::cout << "Sending request to remote server with data: " << data << "\n";
// 发送请求到远程服务器并接收响应
}
};
// 代理类:远程代理
class RemoteServiceProxy : public RemoteService {
private:
std::shared_ptr<ConcreteRemoteService> service;
public:
RemoteServiceProxy() : service(std::make_shared<ConcreteRemoteService>()) {}
void request(const std::string& data) override {
// 在发送请求前可以执行一些额外的操作
std::cout << "Proxy: Preparing request...\n";
// 转发请求给真实的服务对象
service->request(data);
// 在接收响应后可以执行一些额外的操作
std::cout << "Proxy: Processing response...\n";
}
};
int main() {
std::shared_ptr<RemoteService> proxy = std::make_shared<RemoteServiceProxy>();
proxy->request("Some data");
return 0;
}
访问控制代理
假设有一个需要访问控制的对象,只有具有特定权限的用户才能访问。访问控制代理可以用来控制对对象的访问。
#include <iostream>
#include <string>
// 受保护对象
class ProtectedResource {
private:
std::string data;
public:
ProtectedResource(const std::string& data) : data(data) {}
void access(const std::string& user) {
if (user == "admin") {
std::cout << "Accessing resource: " << data << "\n";
} else {
std::cout << "Access denied for user: " << user << "\n";
}
}
};
// 代理类:访问控制代理
class AccessControlProxy {
private:
std::shared_ptr<ProtectedResource> resource;
public:
AccessControlProxy(const std::string& data) : resource(std::make_shared<ProtectedResource>(data)) {}
void access(const std::string& user) {
resource->access(user);
}
};
int main() {
AccessControlProxy proxy("Sensitive data");
proxy.access("user");
proxy.access("admin");
return 0;
}
总结
代理模式可以在不同的场景中使用,包括延迟加载、隐藏远程调用细节和访问控制等。同时,代理模式也可以帮助我们控制对对象的访问,并在访问对象前后执行一些额外的操作。