代理模式(Proxy)是一种结构性设计模式,通过引入一个代理对象来控制对目标对象的访问。
特点
1、代理对象:代理对象代表真实的目标对象,负责控制对目标的访问。
2、多种代理类型:可以有不同类型的代理,例如虚代理、远程代理和保护代理等。
3、延迟加载:代理可以在需要时才加载真实对象,节省资源。
适合场景
1、当需要控制对对象的访问,例如限制权限或提供安全保护。
2、当需要延迟加载某些资源,以提高性能。
3、当需要在客户端和真实对象之间添加额外的功能,例如日志记录、性能监控等。
示例
考虑一个图像加载的场景,在实际应用中,图像可能非常大,加载时间较长。可以使用代理模式创建一个虚代理,只有在实际需要时才加载真实的图像。
//g++ -o test main.cpp
#include <iostream>
#include <memory>
// 抽象主题
class Image {
public:
virtual void display() = 0;
virtual ~Image() = default;
};
// 真实主题
class RealImage : public Image {
public:
RealImage(const std::string& filename) : filename(filename) {
loadImageFromDisk(); // 实际加载图像
}
void display() override {
std::cout << "Displaying " << filename << std::endl;
}
private:
std::string filename;
void loadImageFromDisk() {
std::cout << "Loading " << filename << std::endl;
}
};
// 代理类
class ProxyImage : public Image {
public:
ProxyImage(const std::string& filename) : filename(filename), realImage(nullptr) {}
void display() override {
if (!realImage) {
realImage = std::make_unique<RealImage>(filename); // 延迟加载
}
realImage->display();
}
private:
std::string filename;
std::unique_ptr<RealImage> realImage; // 代理持有真实对象
};
// 客户端代码
int main() {
Image* image = new ProxyImage("example.jpg");
// 图像并未加载,调用 display() 方法时才加载
image->display(); // "Loading example.jpg" 和 "Displaying example.jpg"
image->display(); // 只显示 "Displaying example.jpg"
delete image; // 清理内存
return 0;
}
在这个示例中,ProxyImage 是一个代理类,它延迟加载真实的图像对象 RealImage。当第一次调用 display() 时,代理会创建真实对象并加载图像;后续调用则直接显示图像,而不再重复加载。这样可以有效地节省资源并提高性能。