代理模式是一种结构型设计模式,允许通过代理对象来控制对其他对象的访问。代理模式可以在不改变真实对象的情况下,提供额外的控制逻辑,如访问控制、延迟加载、日志记录等
代理模式的组成
代理模式主要由以下几个部分组成:
- 接口 (Subject):定义真实对象和代理对象共有的接口,保证代理对象和真实对象可以互换使用。
- 真实对象 (RealSubject):实际处理请求的对象。
- 代理对象 (Proxy):控制对真实对象的访问,通常会在调用真实对象的方法之前或之后执行一些额外的操作。
代理模式的应用场景
- 远程代理:为某个位于不同地址空间的对象提供本地代理,屏蔽对象间的通信细节。
- 虚拟代理:通过代理对象来管理需要大量资源的对象创建过程(如延迟加载)。
- 保护代理:用于控制对某些对象的访问权限。
小Demo:Qt C++ 实现代理模式
我们用一个简单的例子来展示代理模式的实现。在这个例子中,RealImage
是实际的图像类,而 ImageProxy
是代理类,它会控制 RealImage
的访问,延迟加载图像,直到真正需要时再加载。
#include <iostream>
#include <QString>
// 定义图片接口(Subject)
class Image {
public:
virtual void display() = 0;
virtual ~Image() {}
};
// 真实的图片类 (RealSubject)
class RealImage : public Image {
private:
QString fileName;
public:
RealImage(const QString& file) : fileName(file) {
loadFromDisk(fileName);
}
void display() override {
std::cout << "Displaying image: " << fileName.toStdString() << std::endl;
}
private:
void loadFromDisk(const QString& file) {
std::cout << "Loading image from disk: " << file.toStdString() << std::endl;
}
};
// 图片代理类 (Proxy)
class ImageProxy : public Image {
private:
RealImage* realImage;
QString fileName;
public:
ImageProxy(const QString& file) : fileName(file), realImage(nullptr) {}
~ImageProxy() {
delete realImage;
}
void display() override {
// 延迟加载:只有在需要时才创建 RealImage 对象
if (realImage == nullptr) {
realImage = new RealImage(fileName);
}
realImage->display();
}
};
// Client 使用代理模式
int main() {
Image* image = new ImageProxy("test_image.jpg");
// 图像尚未加载,代理控制了访问
std::cout << "Image not loaded yet." << std::endl;
// 首次访问图像,加载后显示
image->display();
// 再次访问图像,不会重新加载
image->display();
delete image;
return 0;
}
输出结果:
Image not loaded yet.
Loading image from disk: test_image.jpg
Displaying image: test_image.jpg
Displaying image: test_image.jpg
解析:
- 接口 (Image) 定义了
display
方法,保证RealImage
和ImageProxy
都可以通过相同的接口使用。 - 真实对象 (RealImage) 实现了实际的图像加载和显示操作。
- 代理对象 (ImageProxy) 控制对
RealImage
的访问,在第一次调用display
时才实际加载图像。
优点:
- 控制访问:代理对象可以控制对真实对象的访问,比如权限验证、日志记录等。
- 延迟加载:虚拟代理模式下,只有在真正需要使用对象时才加载它,节省资源。
结论:
代理模式通过增加一个代理对象来控制对真实对象的访问,提供了更灵活的控制手段。在 Qt C++ 开发中,可以通过这种模式来优化资源使用,特别是在处理大型资源或远程对象时非常有用。