C++实现设计模式---代理模式 (Proxy)

代理模式 (Proxy)

代理模式 是一种结构型设计模式,它为其他对象提供一个代理以控制对该对象的访问。代理模式常用于延迟加载、访问控制、智能引用等场景。


意图

  • 提供对某对象的控制。
  • 控制对目标对象的访问,通常用于在不改变目标对象的情况下,附加额外的功能。
  • 常见于延迟加载、权限控制等场景。

使用场景

  1. 远程代理

    • 当对象存在于不同的地址空间时,代理模式提供了对远程对象的访问。
  2. 虚拟代理

    • 延迟对象的创建,只有在需要时才创建对象,避免不必要的资源消耗。
  3. 保护代理

    • 控制对某个对象的访问权限。代理对象负责控制访问。
  4. 智能代理

    • 对对象访问进行计数、缓存等操作。例如,记录访问次数、管理缓存等。

参与者角色

  1. 主题接口 (Subject)

    • 定义了目标对象和代理类的公共接口。
  2. 真实主题 (RealSubject)

    • 实现了 Subject 接口的目标对象,包含实际业务逻辑。
  3. 代理 (Proxy)

    • 代理类,持有真实主题对象的引用,代理请求到真实主题对象,附加控制逻辑。

示例代码

以下代码展示了如何使用代理模式控制对一个图片加载的访问。

cpp 复制代码
#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 方法。
cpp 复制代码
class Image {
public:
    virtual ~Image() = default;
    virtual void display() = 0;
};

2. 真实主题

  • RealImage 类是实际的图片对象,提供了加载和显示图片的功能。
  • loadImage 在构造函数中被调用,用于模拟加载图片。
cpp 复制代码
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 是否已被创建。如果尚未创建,则延迟加载它。
cpp 复制代码
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 的访问,并在必要时创建它。
cpp 复制代码
int main() {
    Image* image1 = new ProxyImage("image1.jpg");
    Image* image2 = new ProxyImage("image2.jpg");

    image1->display(); // 加载并显示
    image2->display(); // 加载并显示

    image1->display(); // 直接显示
    delete image1;
    delete image2;
}

优缺点

优点

  1. 延迟初始化

    • 代理模式可以在需要时才创建和初始化对象,避免不必要的资源消耗。
  2. 控制访问权限

    • 代理对象可以控制对真实对象的访问,如权限控制、延迟加载等。
  3. 增加功能而不改变目标对象

    • 通过代理,可以为目标对象添加附加功能,而无需修改目标对象。

缺点

  1. 增加系统复杂度

    • 代理模式增加了对象间的间接性,可能导致系统变得复杂。
  2. 性能开销

    • 使用代理时,可能会有额外的性能开销,特别是在频繁调用代理方法时。

适用场景

  1. 远程代理

    • 访问远程对象时,代理对象可以替代真实对象,并处理通信。
  2. 虚拟代理

    • 延迟对象的加载,当需要时才创建对象,避免不必要的资源消耗。
  3. 保护代理

    • 控制对真实对象的访问权限,确保只有符合条件的用户才能访问。

总结

代理模式通过提供一个替代的对象来控制对真实对象的访问。它广泛用于延迟加载、权限控制、远程调用等场景,能够有效提高系统的灵活性和可扩展性。

相关推荐
泽02021 小时前
C++入门(缺省参数/函数/引用)
开发语言·c++
mozun20205 小时前
VS BUG(6) LINK : fatal error LNK1158: 无法运行“rc.exe”
c++·bug·vs·链接器·资源文件
whoarethenext6 小时前
初始https附带c/c++源码使用curl库调用
服务器·c++·qt·https·curl
此木|西贝6 小时前
【设计模式】享元模式
java·设计模式·享元模式
cloues break.7 小时前
C++进阶----多态
开发语言·c++
Despacito0o7 小时前
C++核心编程:类与对象全面解析
开发语言·c++
麓殇⊙8 小时前
设计模式--建造者模式详解
设计模式·建造者模式
不当菜虚困8 小时前
JAVA设计模式——(八)单例模式
java·单例模式·设计模式
Java致死9 小时前
工厂设计模式
java·设计模式·简单工厂模式·工厂方法模式·抽象工厂模式
全栈凯哥10 小时前
桥接模式(Bridge Pattern)详解
java·设计模式·桥接模式