代理模式 (Proxy)
代理模式 是一种结构型计划模式,它为其他对象提供一个代理以控制对该对象的访问。代理模式常用于耽误加载、访问控制、智能引用等场景。
意图
- 提供对某对象的控制。
- 控制对目标对象的访问,通常用于在不改变目标对象的情况下,附加额外的功能。
- 常见于耽误加载、权限控制等场景。
使用场景
- 长途代理
- 当对象存在于不同的地址空间时,代理模式提供了对长途对象的访问。
- 虚拟代理
- 耽误对象的创建,只有在须要时才创建对象,避免不须要的资源消耗。
- 保护代理
- 智能代理
- 对对象访问举行计数、缓存等操作。例如,记录访问次数、管理缓存等。
参与者角色
- 主题接口 (Subject)
- 真实主题 (RealSubject)
- 实现了 Subject 接口的目标对象,包罗实际业务逻辑。
- 代理 (Proxy)
- 代理类,持有真实主题对象的引用,代理哀求到真实主题对象,附加控制逻辑。
示例代码
以下代码展示了怎样使用代理模式控制对一个图片加载的访问。
- #include <iostream>
- #include <string>
- // 主题接口
- class Image {
- public:
- virtual ~Image() = default;
- virtual void display() = 0; // 移除 const
- };
- // 真实主题:加载并显示图片
- class RealImage : public Image {
- private:
- std::string filename;
- public:
- RealImage(const std::string& file) : filename(file) {
- loadImage();
- }
- void loadImage() const {
- std::cout << "Loading image: " << filename << std::endl;
- }
- void display() override {
- std::cout << "Displaying image: " << filename << std::endl;
- }
- };
- // 代理类:代理真实图片加载和显示
- class ProxyImage : public Image {
- private:
- RealImage* realImage;
- std::string filename;
- public:
- ProxyImage(const std::string& file) : filename(file), realImage(nullptr) {}
- void display() override {
- if (!realImage) {
- realImage = new RealImage(filename); // 延迟加载真实图像
- }
- realImage->display();
- }
- ~ProxyImage() {
- delete realImage;
- }
- };
- // 客户端代码
- int main() {
- Image* image1 = new ProxyImage("image1.jpg");
- Image* image2 = new ProxyImage("image2.jpg");
- // 第一次访问时加载并显示图片
- image1->display();
- image2->display();
- // 直接显示图片,不会重新加载
- image1->display();
- delete image1;
- delete image2;
- return 0;
- }
复制代码 代码解析
1. 主题接口
- Image 类定义了目标对象和代理类的公共接口。
- 全部的图片类都须要实现 display 方法。
- class Image {
- public:
- virtual ~Image() = default;
- virtual void display() = 0;
- };
复制代码 2. 真实主题
- RealImage 类是实际的图片对象,提供了加载和显示图片的功能。
- loadImage 在构造函数中被调用,用于模拟加载图片。
- class RealImage : public Image {
- private:
- std::string filename;
- public:
- RealImage(const std::string& file) : filename(file) {
- loadImage();
- }
- void loadImage() const {
- std::cout << "Loading image: " << filename << std::endl;
- }
- void display() override {
- std::cout << "Displaying image: " << filename << std::endl;
- }
- };
复制代码 3. 代理类
- ProxyImage 类是一个代理类,它控制对 RealImage 的访问。
- 在 display 方法中,它会先检查 realImage 是否已被创建。如果尚未创建,则耽误加载它。
- class ProxyImage : public Image {
- private:
- RealImage* realImage;
- std::string filename;
- public:
- ProxyImage(const std::string& file) : filename(file), realImage(nullptr) {}
- void display() override {
- if (!realImage) {
- realImage = new RealImage(filename); // 延迟加载真实图像
- }
- realImage->display();
- }
- ~ProxyImage() {
- delete realImage;
- }
- };
复制代码 4. 客户端
- 客户端使用代理类,而不是直接使用真实主题类。
- ProxyImage 控制了对 RealImage 的访问,并在须要时创建它。
- int main() {
- Image* image1 = new ProxyImage("image1.jpg");
- Image* image2 = new ProxyImage("image2.jpg");
- image1->display(); // 加载并显示
- image2->display(); // 加载并显示
- image1->display(); // 直接显示
- delete image1;
- delete image2;
- }
复制代码 优缺点
优点
- 耽误初始化:
- 代理模式可以在须要时才创建和初始化对象,避免不须要的资源消耗。
- 控制访问权限:
- 代理对象可以控制对真实对象的访问,如权限控制、耽误加载等。
- 增长功能而不改变目标对象:
- 通过代理,可以为目标对象添加附加功能,而无需修改目标对象。
缺点
- 增长体系复杂度:
- 代理模式增长了对象间的间接性,可能导致体系变得复杂。
- 性能开销:
- 使用代理时,可能会有额外的性能开销,特别是在频繁调用代理方法时。
实用场景
- 长途代理:
- 访问长途对象时,代理对象可以替代真实对象,并处理通信。
- 虚拟代理:
- 耽误对象的加载,当须要时才创建对象,避免不须要的资源消耗。
- 保护代理:
- 控制对真实对象的访问权限,确保只有符合条件的用户才能访问。
总结
代理模式通过提供一个替代的对象来控制对真实对象的访问。它广泛用于耽误加载、权限控制、长途调用等场景,能够有效进步体系的机动性和可扩展性。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |