C++|设计模式(四)|代理模式

代理模式属于结构型设计模式,并不关注与对象的产生,而是类和对象功能的使用;

该类模设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式

比如说我们想要访问某公司的老板,其实不可能是直接打到老板那里,而是先打给助理。这里的助理就是代理proxy的角色。

代理模式主要体现的是对于我们对象即老板的权限控制,不是所有的客户都能够访问老板的。

所以代理模式就是通过代理类。来控制实际对象(老板/委托类)的访问权限。

我们先举一个例子来探讨代理模式的好处。

案例

我们拿视频网站来举例,视频网站有免费的、有VIP的、也有必须要买券购买观看权的。

cpp 复制代码
#include <iostream>
using namespace std;

class VideoSite {
public:
    virtual ~VideoSite() = default;
    virtual void freeMovie() = 0; //免费电影
    virtual void vipMovie() = 0;  //vip电影
    virtual void tickMovie() = 0; //用券观看
};

class FixBugVideoSite : public VideoSite {
public:
    void freeMovie() override { //免费电影
        cout << "观看免费电影" << endl;  
    }
    void vipMovie() override { //vip电影
        cout << "观看vip电影" << endl;
    }
    void tickMovie() override {//用券观看
        cout << "用券观看电影" << endl;
    }
};

我们开始看电影:

cpp 复制代码
int main () {
    VideoSite *p1 = new FixBugVideoSite();

    p1->freeMovie();
    p1->vipMovie();
    p1->tickMovie();
}

我们直接就可以看各类电影,达不到我们设计的初衷,应该每一类电影都需要有权限设置。


所以我们需要加代理类,代理的就是我们的FixBugVideoSite,不允许客户指针直接指向我们的委托类对象FixBugVideoSite,而是指向我们的代理类对象,用代理对象来控制客户对委托类访问对象权限的问题。

cpp 复制代码
//代理类,代理的就是我们的FixBugVideoSite
class FreeVideoSiteProxy : public VideoSite {
public:
    FreeVideoSiteProxy() { pVideo = new FixBugVideoSite(); }
    ~FreeVideoSiteProxy() { delete pVideo; }

    //通过代理对象的freeMovie来访问真正委托类对象的方法
    virtual void freeMovie() { pVideo->freeMovie(); } 
    virtual void vipMovie() { 
        cout << "您目前只是普通游客,需要升级成vip才能观看vip电影" << endl; 
    }
    virtual void tickMovie() {
        cout << "你目前没有电影券,该电影您需要买券观看" << endl;
    }

private:
    VideoSite *pVideo;
};

在调用时,也只允许我们的客户指针指向代理类;

cpp 复制代码
#include <memory>
int main () {
    unique_ptr<VideoSite> p1(new FreeVideoSiteProxy());

    p1->freeMovie();
    p1->vipMovie();
    p1->tickMovie();
}
/*输出
观看免费电影
您目前只是普通游客,需要升级成vip才能观看vip电影
你目前没有电影券,该电影您需要买券观看
*/

在这里我们只实现了免费客户的代理类,其他级别的代理类可以自行实现。

总结

首先我们需要有

  1. 公共的抽象类;
cpp 复制代码
class VideoSite {
public:
    virtual ~VideoSite() = default;
    virtual void freeMovie() = 0; //免费电影
    virtual void vipMovie() = 0;  //vip电影
    virtual void tickMovie() = 0; //用券观看
};
  1. 委托类。它需要从公共的抽象类继承而来。
cpp 复制代码
class FixBugVideoSite : public VideoSite {
public:
    void freeMovie() override { //免费电影
        cout << "观看免费电影" << endl;  
    }
    void vipMovie() override { //vip电影
        cout << "观看vip电影" << endl;
    }
    void tickMovie() override {//用券观看
        cout << "用券观看电影" << endl;
    }
};
  1. 代理类。
cpp 复制代码
class FreeVideoSiteProxy : public VideoSite {
public:
    FreeVideoSiteProxy() { pVideo = new FixBugVideoSite(); }
    ~FreeVideoSiteProxy() { delete pVideo; }
    virtual void freeMovie() { pVideo->freeMovie(); } 
    virtual void vipMovie() { 
        cout << "您目前只是普通游客,需要升级成vip才能观看vip电影" << endl; 
    }
    virtual void tickMovie() {
        cout << "你目前没有电影券,该电影您需要买券观看" << endl;
    }
private:
    VideoSite *pVideo;
};
  1. 以组合的方式来使用我们的代理对象。也就是委托类的成员变量,用来对外提供借口。
cpp 复制代码
private:
    VideoSite *pVideo;

private:
	FixBugVideoSite Video;//这样写灵活性较差
  1. 客户直接访问代理对象
cpp 复制代码
 unique_ptr<VideoSite> p1(new FreeVideoSiteProxy());
相关推荐
滨HI026 分钟前
C++ opencv简化轮廓
开发语言·c++·opencv
学习路上_write40 分钟前
FREERTOS_互斥量_创建和使用
c语言·开发语言·c++·stm32·单片机·嵌入式硬件
未秃头的程序猿1 小时前
🚀 设计模式在复杂支付系统中的应用:策略+工厂+模板方法模式实战
后端·设计模式
雨中飘荡的记忆2 小时前
深入理解设计模式之单例模式
java·设计模式
闻缺陷则喜何志丹2 小时前
【SOSDP模板 容斥原理 逆向思考】3757. 有效子序列的数量|分数未知
c++·算法·力扣·容斥原理·sosdp·逆向思考
BestOrNothing_20152 小时前
一篇搞懂 C++ 重载:函数重载 + 运算符重载,从入门到会用(含 ++、<<、== 实战)
c++·函数重载·运算符重载·operator·前置后置++·重载与重写
2501_941144423 小时前
Python + C++ 异构微服务设计与优化
c++·python·微服务
程序猿编码3 小时前
PRINCE算法的密码生成器:原理与设计思路(C/C++代码实现)
c语言·网络·c++·算法·安全·prince
8***29313 小时前
能懂!基于Springboot的用户增删查改(三层设计模式)
spring boot·后端·设计模式
charlie1145141914 小时前
深入理解C/C++的编译链接技术6——A2:动态库设计基础之ABI设计接口
c语言·开发语言·c++·学习·动态库·函数