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

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

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

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

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

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

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

案例

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

#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;}
};

我们开始看电影:

int main () {VideoSite *p1 = new FixBugVideoSite();p1->freeMovie();p1->vipMovie();p1->tickMovie();
}

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


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

//代理类,代理的就是我们的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;
};

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

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

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

总结

首先我们需要有

  1. 公共的抽象类;
class VideoSite {
public:virtual ~VideoSite() = default;virtual void freeMovie() = 0; //免费电影virtual void vipMovie() = 0;  //vip电影virtual void tickMovie() = 0; //用券观看
};
  1. 委托类。它需要从公共的抽象类继承而来。

class FixBugVideoSite : public VideoSite {
public:void freeMovie() override { //免费电影cout << "观看免费电影" << endl;  }void vipMovie() override { //vip电影cout << "观看vip电影" << endl;}void tickMovie() override {//用券观看cout << "用券观看电影" << endl;}
};
  1. 代理类。
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. 以组合的方式来使用我们的代理对象。也就是委托类的成员变量,用来对外提供借口。
private:VideoSite *pVideo;

private:FixBugVideoSite Video;//这样写灵活性较差
  1. 客户直接访问代理对象
 unique_ptr<VideoSite> p1(new FreeVideoSiteProxy());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/840622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全栈式数据统计:SqlAlchemy怎样连接MsSql Server获取视图列表

1.源代码 #-----------获取数据库视图列表----------------------------- # -------密码含特殊字符使用 from urllib.parse import quote_plus as urlquotefrom sqlalchemy import create_engine, MetaData, inspect# 替换为你的数据库连接字符串 DRIVER "ODBC Driver 1…

c++的查漏补缺 1、函数指针

今天写链表的插入排序时遇到了一个问题 void InsertionSortList(ListNode* head, int n){if (!head||!head->next) return nullptr;auto dummy new ListNode(-1);dummy->next head;auto pre head;auto cur head->next;while (cur ! NULL){auto tmp dummy;if (pre…

【新】snapd申请Let‘s Encrypt免费SSL证书、自动化续签证书

简介 之前写过一篇certbot申请SSL证书的文章&#xff1a;SSL证书申请&#xff0c;写得比较详细&#xff0c;但是最近发现使用snapd会更方便。 使用机器&#xff1a;Ubuntu 20.04 简单步骤 1、首先安装必要软件 sudo apt install snapd sudo apt install certbot sudo apt …

可视化在医疗健康领域的巨大价值,该如何设计呢。

可视化设计在医疗健康领域具有以下价值&#xff1a; 数据展示与分析&#xff1a;可视化设计可以将医疗健康领域的大量数据以图表、图形等形式进行展示和分析&#xff0c;帮助医生、研究人员和决策者更直观地理解和解读数据&#xff0c;发现规律和趋势&#xff0c;从而做出科学决…

有效的完全平方数-力扣

在使用二分法完成题目时&#xff0c;使用如下条件判断时 if(mid < num/mid)当输入 num 5&#xff0c;当二分查找到 mid 2时&#xff0c; 出现了mid num/mid的情况&#xff0c;暴露出了这种判断条件的缺陷。 class Solution { public:bool isPerfectSquare(int num) {i…

力扣 10. 正则表达式匹配 python AC

动态规划 class Solution:def isMatch(self, s, p):s sp psize1 len(p)size2 len(s)dp [[False] * size2 for _ in range(size1)]# p到i和s到j为止&#xff0c;是否匹配dp[0][0] Truefor i in range(size1):for j in range(size2):if p[i] .:if p[i - 1] * and …

跨语言摘要CLS近期论文研究总结(二)

1.BART: Denoising Sequence-to-Sequence Pre-training for Natural Language Generation, Translation, and Comprehension 自然语言生成&#xff0c;翻译和理解的去噪序列到序列预训练 BART的训练方法是: (1)以任意的加噪方式对文本进行破坏 (2)学习一个模型来重建原始文本…

【NOI2010】能量采集 题解

推荐在 cnblogs 上阅读。 【NOI2010】能量采集 题解 谨纪念我的第一道手推出来的莫反题。 题目大意&#xff1a;已知 n n n&#xff0c; m m m&#xff0c;求 ∑ i 1 n ∑ j 1 m ( 2 ⋅ gcd ⁡ ( i , j ) − 1 ) \sum\limits_{i1}^n\sum\limits_{j1}^m(2\cdot \gcd(i,j)…

CMU15-445-并发控制,事务实现

事务并发控制 CMU15-445概览 2PL代表两阶段锁协议&#xff08;Two-phase locking&#xff09;。这是一种并发控制机制&#xff0c;用于关系数据库系统中以保障数据完整性。在这种机制中&#xff0c;事务的执行被划分为两个阶段&#xff1a;加锁阶段和释放锁阶段。加锁阶段发生…

Spring相关知识集锦----2

一、Spring循环依赖三级缓存解决方式 singletonObjects:一级缓存 earlySingletonObjects:二级缓存 singletonFactories:三级缓存 spring如何使用三级缓存解决循环依赖&#xff1a; 1.a实例化完成后&#xff0c;将a放入三级缓存 2.初始化a&#xff0c;又去创建b 3.b实例化…

C++高效死锁检测——实现原理与应用(基于强连通分量)

背景 在项目使用多进程、多线程过程中&#xff0c;因争夺资源而造成一种资源竞态&#xff0c;所以需加锁处理。如下图所示&#xff0c;线程 A 想获取线程 B 的锁&#xff0c;线程 B 想获取线程 C 的锁&#xff0c;线程 C 想获取线程 D 的锁&#xff0c; 线程 D 想获取线程 A 的…

回溯大法总结

前言 本篇博客将分两步来进行&#xff0c;首先谈谈我对回溯法的理解&#xff0c;然后通过若干道题来进行讲解&#xff0c;最后总结 对回溯法的理解 回溯法可以看做蛮力法的升级版&#xff0c;它在解决问题时的每一步都尝试所有可能的选项&#xff0c;最终找出所以可行的方案…

c++11 标准模板(STL)本地化库 - 平面类别(std::numpunct_byname) 表示系统提供的具名本地环境的 std::numpunct

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 表示系统提供的具名本地环境的 std::numpunct std::numpunct_byn…

【Git】版本控制工具——Git介绍及使用

目录 版本控制版本控制系统的主要目标分类小结 分布式版本控制系统——GitGit特点Git与SVN的区别Git的工作机制 Git安装Git 团队协作机制团队内协作跨团队协作远程仓库远程仓库的作用有以下几个方面远程仓库操作流程/团队协作流程 Git分支什么是分支分支的好处 Git的常用命令Gi…

【热门话题】CentOS 常见命令指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 CentOS 常见命令指南一、文件与目录操作1. 切换目录2. 查看当前目录3. 列出目录…

周报5.20~5.26

学习内容&#xff1a; 主要了解了Qt的信号和槽、ui页面布局、各类常见控件的使用、绘图事件以及文件操作的相关知识&#xff0c;并且完成相关案例的设计。练习代码了解了多层感知机、激活函数、多项式回归、高维线性回归、暂退法、分布偏移、深度学习计算等相关知识与代码案例…

微信小程序中Button组件的属性值和用法详解

在微信小程序开发中&#xff0c;Button组件是非常常用的UI组件之一&#xff0c;它可以让用户进行交互操作&#xff0c;比如提交表单、跳转页面等。了解Button组件的属性值和用法对于开发者来说至关重要。 1. Button组件简介 简要介绍Button组件在小程序中的作用和重要性&…

SVM影像组学特征

近期做一个影像组学的分类模型 做的是一个胃癌T分期的模型&#xff0c;我刷选统计出一些胃癌区域的特征&#xff0c;如图&#xff1a;有癌症面积、体积等等 下面要做一个SVM&#xff08;支持向量机&#xff09;分类的模型&#xff0c;导入该文件&#xff0c;进行二分类&#x…

MFC密码对话框之间数据传送实例(源码下载)

新建一个login工程项目对话框&#xff0c;主对话框IDD_LOGIN_DIALOG中一个显示按钮IDC_BUTTON1、一个密码按钮IDC_BUTTON2。添加一个密码对话框IDD_DIALOG1&#xff0c;添加类password&#xff0c;在对话框中添加一个编辑框IDC_EDIT1、一个确定按钮IDC_BUTTON1。 程序功能&…