C++设计模式之代理模式

动机

在面向对象系统中,有些对象由于某种原因(比如对象创建的开销很大,或者某些操作需要安全控制,或者需要进程外的访问等),直接访问会给使用者、或者系统结构带来很多麻烦。

如何在不失去透明操作对象的同时来管理/控制这些对象特有的复 杂性?增加一层间接层是软件开发中常见的解决方式。

代码示例

cpp 复制代码
class ISubject{
public:
    virtual void process();
};


//Proxy的设计
class SubjectProxy: public ISubject{
    
    
public:
    virtual void process(){
        //对RealSubject的一种间接访问
        //....
    }
};

class ClientApp{
    
    ISubject* subject;
    
public:
    
    ClientApp(){
        subject=new SubjectProxy();
    }
    
    void DoTask(){
        //...
        subject->process();
        
        //....
    }
};

Proxy模式定义

为其他对象提供一种代理以控制对这个对象的访问。

以下是一个简单的 C++ 代理模式的例子,其中实现了一个图片加载的代理。

cpp 复制代码
#include <iostream>
#include <string>

// Subject 接口
class Image {
public:
    virtual void display() const = 0;
};

// RealSubject 类
class RealImage : public Image {
private:
    std::string filename;

public:
    RealImage(const std::string& filename) : filename(filename) {
        loadImage();
    }

    void loadImage() {
        std::cout << "Loading image: " << filename << std::endl;
    }

    void display() const override {
        std::cout << "Displaying image: " << filename << std::endl;
    }
};

// Proxy 类
class ImageProxy : public Image {
private:
    RealImage* realImage;
    std::string filename;

public:
    ImageProxy(const std::string& filename) : realImage(nullptr), filename(filename) {}

    void display() const override {
        if (realImage == nullptr) {
            realImage = new RealImage(filename);
        }
        realImage->display();
    }
};

// Client 代码
int main() {
    // 使用代理加载图片,实际图片加载在需要显示时进行
    Image* image = new ImageProxy("sample.jpg");

    // 第一次显示图片,会触发加载
    image->display();

    // 第二次显示图片,直接使用已加载的图片
    image->display();

    return 0;
}

在这个例子中,Image 是代理模式的 Subject 接口,RealImage 是 RealSubject 类,负责实际加载和显示图片。ImageProxy 是代理类,用于延迟加载和控制对 RealImage 对象的访问。客户端通过代理类使用图片,代理类在需要时创建或使用实际图片对象。
要点总结

"增加一层间接层"是软件系统中对许多复杂问题的一种常见解 决方法。在面向对象系统中,直接使用某些对象会带来很多问题, 作为间接层的proxy对象便是解决这一问题的常用手段。

具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模块提供抽象代理层,在架构层次对对象做proxy。

Proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时候损及一些透明性是可以接受的。

相关推荐
研究点啥好呢2 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
_dindong2 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
沫璃染墨2 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
6Hzlia3 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
计算机安禾3 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
unicrom_深圳市由你创科技3 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
无限进步_4 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
C++ 老炮儿的技术栈4 小时前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt
橘颂TA4 小时前
【笔试】算法的暴力美学——牛客 NC213140 :除2!
c++·算法·结构与算法
wsoz5 小时前
Leetcode普通数组-day5、6
c++·算法·leetcode·数组