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. 保护代理

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

总结

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

相关推荐
陌然。。1 分钟前
【39. 组合总和 中等】
数据结构·c++·笔记·算法·leetcode
Say-hai1 小时前
QT中的字符串类型
网络·c++·qt
難釋懷2 小时前
解释器模式
设计模式·解释器模式
不如学也2 小时前
c++ 17 constexpr
开发语言·c++
baiyu332 小时前
C++ Primer Notes(4): 变量初始化和作用域
c++
IOT-Power3 小时前
<C++学习> C++ Boost 字符串操作教程
c++
1e-123 小时前
【数据结构高阶】B-树
数据结构·c++·b树
誓约酱3 小时前
Linux下文件操作相关接口
linux·运维·服务器·c语言·c++·后端
赵宁灬学长4 小时前
23种设计模式
设计模式
计算机小混子4 小时前
C++实现设计模式---策略模式 (Strategy)
c++·设计模式·策略模式