代理模式是一种设计模式,用于提供一个代理对象来控制对另一个对象的访问。这种模式创建了一个具有原始对象相同接口的代理对象,从而可以在不改变客户端代码的情况下控制对原始对象的访问。代理模式主要用于延迟处理操作或访问,访问控制,日志记录等。这里,我们将使用C++来实现一个简单的代理模式示例。
想象一下,我们有一个Image
接口,它有一个display
方法。我们将有两个实现了Image
接口的类:RealImage
代表一个需要加载的重量级图片资源,以及ProxyImage
,作为RealImage
对象的代理,用于控制对RealImage
对象的访问。
Step 1: 定义Image
接口
cpp
class Image {
public:
virtual void display() = 0; // 纯虚函数,需要在派生类中实现
virtual ~Image() {} // 虚析构函数以支持多态删除
};
Step 2: 实现RealImage
类
cpp
#include <iostream>
#include <string>
class RealImage : public Image {
private:
std::string filename;
public:
RealImage(const std::string& filename) : filename(filename) {
loadFromDisk(filename); // 模拟从磁盘加载图片
}
void display() override {
std::cout << "Displaying " << filename << std::endl;
}
void loadFromDisk(const std::string& filename) {
std::cout << "Loading " << filename << std::endl;
}
};
Step 3: 实现ProxyImage
类
cpp
class ProxyImage : public Image {
private:
std::string filename;
RealImage* realImage; // 指向真实对象的指针
public:
ProxyImage(const std::string& filename) : filename(filename), realImage(nullptr) {}
void display() override {
if (realImage == nullptr) {
realImage = new RealImage(filename); // 第一次访问时才加载图片
}
realImage->display();
}
~ProxyImage() {
delete realImage; // 清理资源
}
};
Step 4: 使用ProxyImage
来获取Image
对象
cs
int main() {
Image* image = new ProxyImage("test_10mb.jpg");
// 图像将从磁盘加载
image->display();
std::cout << "Image displayed.\n";
// 图像不需要从磁盘加载
image->display();
std::cout << "Image displayed again.\n";
delete image; // 清理资源
return 0;
}
这个例子展示了代理模式的基本用法:ProxyImage
类控制对RealImage
类的访问,包括其创建和显示。RealImage
的创建只有在实际需要时(即第一次调用display
方法时)才会进行,这种延迟加载是代理模式的一种常见用途。通过这种方式,我们可以避免在对象实际使用之前加载重量级资源,从而提高应用的性能。