设计模式之代理模式(C++)
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、代理模式是什么?
代理模式是一种结构型的软件设计模式,在不改变原代码前提下,提供一个代理,以控制对原对象的访问。
代理模式的优点:
- 职责清晰。真实对象专注于自身业务逻辑,不用考虑其他非本职内容,交给代理完成。
- 高拓展性。真实对象的改变不影响代理。
- 解耦。将客户端与真实对象分离,降低系统耦合度。
- 提高性能。虚拟代理可以减少系统资源的消耗。
- 高安全性和稳定性。代理能很好地控制访问,提高程序安全。
代理模式的缺点:
- 增加系统复杂度。代理的职责往往较冗杂。
- 请求速度降低。客户端与真实对象中加入代理,一定程度上会降低整个系统流程的运行效率。
二、代理模式
2.1 结构图
客户端即Main主函数,本文示例中代理添加了额外功能-充值,因此客户端直接调用代理。

2.2 代码示例
场景描述:游戏往往有自己的代理商,想要玩魔兽,需要和其代理进行沟通,在进行充值后,正常游戏。
//Game.h
/****************************************************/
#pragma once
#include <iostream>using namespace std;#include <iostream>
using namespace std;// 抽象游戏类
class Game
{
public:// 游戏加载virtual void load() = 0;// 游戏退出virtual void exit() = 0;
};// 真实游戏类-魔兽世界
class WOW : public Game
{
public:// 游戏加载virtual void load() {cout << "魔兽世界加载。" << endl;}// 游戏退出virtual void exit() {cout << "魔兽世界退出。" << endl;}
};// 代理类-魔兽代理
class ProxyWOW : public Game
{
public:// 构造函数ProxyWOW() {m_wow = new WOW();}// 析构函数virtual ~ProxyWOW() {if (m_wow != nullptr) {delete m_wow;m_wow = nullptr;}}// 充值时间void recharge(int money) {m_time += money / 100;cout << "充值:" << money << endl;cout << "获得时长:" << m_time << endl;}// 游戏加载virtual void load() {cout << "代理启动。" << endl;if (m_time > 0) {m_wow->load();cout << "游戏时长1小时。" << endl;m_time -= 1;cout << "剩余时长:" << m_time << endl;flag = true;}else {cout << "剩余游戏时长不足,请充值。" << endl;flag = false;}}// 游戏退出virtual void exit() {if (flag) {m_wow->exit();flag = false;}cout << "代理关闭。" << endl;}private:bool flag = false;int m_time = 0;WOW* m_wow;
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Subject.h"using namespace std;int main()
{// 玩魔兽ProxyWOW* proxy = new ProxyWOW();// 加载proxy->load();// 充值proxy->recharge(1000);// 加载proxy->load();// 退出proxy->exit();// 清理内存delete proxy;proxy = nullptr;return 0;}
程序结果如下。

本文提供的示例是游戏方面的,玩大型网络游戏往往都要通过代理的平台,所以我模拟了一个简易的充值和游戏流程。代理在生活中随处可见,各种中介服务就是代理的一种;在网络应用中代理也很常见,如服务器代理等等。
三、总结
我尽可能用较通俗的话语和直观的代码例程,来表述我对代理模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解代理模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
相关文章:
设计模式之代理模式(C++)
作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 一、代理模式是什么? 代理模式是一种结构型的软件设计模式,在不改变原代码前提下,提供一个代理…...
c++11 标准模板(STL)(std::unordered_multimap)(三)
定义于头文件 <unordered_map> template< class Key, class T, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator< std::pair<const Key, T> > > class unordered…...
Linux进程控制-2
紧接着上篇博客出发,我们接着来讲述Linux中进程控制的内容。 目录 1.等待 1.1具体操作 1.等待 进程等待主要的作用在于:父进程创建子进程之后,等待子进程退出,获取子进程的退出码,释放子进程的资源,避…...
快速排序算法
一:快速排序思想 假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便ÿ…...
中华好诗词大学季第二季(四)
第七期 1,二十四友一朝尽,爱妾坠楼何足言出自许浑的《金谷园》,“爱妾”指的是谁 2,李白在《九月十日即事》借菊花表达自己的惋惜之情,请问九月十日是什么节日 A 后登高 B 菊花节 C 小重阳 3,贾宝玉在大观园里面题了“曲径通幽”…...
分布式系统容灾部署方案
本文主要以OceanBase部署来说明分布式系统容灾部署方案 分布式系统提供持续可用的服务尤为重要。 好的分布式系统根据需求提供不同等级的的高可用与容灾级别。 而在分布式系统中,数据库系统又是最核心最关键的系统。 我们以数据库分布式系统为主,考虑…...
Python 爬虫性能相关总结
这里我们通过请求网页例子来一步步理解爬虫性能 当我们有一个列表存放了一些url需要我们获取相关数据,我们首先想到的是循环 简单的循环串行 这一种方法相对来说是最慢的,因为一个一个循环,耗时是最长的,是所有的时间总和 代码…...
Baumer工业相机堡盟工业相机如何设置网口的IP地址(工业相机连接的网口设置IP地址步骤)
Baumer工业相机堡盟工业相机如何设置网口的IP地址(工业相机连接的网口设置IP地址步骤)Baumer工业相机Baumer工业相机设置网络端口IP地址匹配设置网络端口IP地址和工业相机IP地址匹配第一次打开CameraExplorer软件确认问题为IP地址不匹配问题打开网络连接…...
Android MediaCodec设置H264 Profile到High
H264 High Profile压缩率高,能降低码率,这里记录下MediaCodec Profile设置到High遇到的一些问题。 Android 4.1 就引入了MediaCodecInfo.CodecProfileLevel类,下面截取H264(AVC)的Profile和Level定义: /** Copyright (C) 2012 The Android O…...
QT之QSysInfo(查看电脑信息)
文章目录前言一、API使用总结前言 QSysInfo是Qt中用于获取有关运行应用程序的系统信息的类。 我们可以获取以下信息: 返回系统产品类型,如ios,windows,Linux等 返回当前系统的产品版本。 返回当前系统的内核类型。 返回当前系统的…...
中国塑料编织袋产业竞争状况及投资前景预测报告2023-2029年
中国塑料编织袋产业竞争状况及投资前景预测报告2023-2029年 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK 《报告编号》: BG451639 《出版时间》: 2023年4月 《出版机构》: 中智正业研究院 免费售后 服务一年,具体内容及订购流程欢迎咨询客服人员 内容简介&…...
从头用脚分析FFmpeg源码 - av_read_frame
av_read_frame作用 /*** Return the next frame of a stream.* This function returns what is stored in the file, and does not validate* that what is there are valid frames for the decoder. It will split what is* stored in the file into frames and return one f…...
第17章_触发器
第17章_触发器 🏠个人主页:shark-Gao 🧑个人简介:大家好,我是shark-Gao,一个想要与大家共同进步的男人😉😉 🎉目前状况:23届毕业生,目前在某公…...
3956. 截断数组
3956. 截断数组 - AcWing题库 3956. 截断数组 【题目描述】 给定一个长度为 nn 的数组 a1,a2,…,ana1,a2,…,an。 现在,要将该数组从中间截断,得到三个非空子数组。 要求,三个子数组内各元素之和都相等。 请问,共有多少种不同…...
React Labs: 我们最近在做什么——2023 年 3 月
原文:https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023 React Server Components React Server Components(下文简称 RSC) 是由 React 团队设计的新应用程序架构。 我们首先在一个介绍性演讲和一个RFC中分享了我们对 RSC 的…...
文件系统设计详解
抽象的文件系统以目录的形式来组织文件,我们可以利用该文件系统来读取某个文件的内容,也可以对目录或者文件实施监控并及时获取变化的通知。 IChangeToken IChangeToken对象就是一个与某组监控数据相关联的“令牌”(Token)&#x…...
好看~立马启动python实现美女通通下
人生苦短,我用python一、环境版本使用二、代码实现思路三、代码展示:导入模块伪装(请求头)四、部分好看截图,更多的就自己去采集噜~吃饭放松的时候哇一不小心看见了很多好看的东西 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 独乐乐不如众乐乐…...
Git 安装设置
1、安装 安装以下三个软件: Git-2.13.3-64-bit.exe TortoiseGit-2.4.0.2-64bit.msi TortoiseGit-LanguagePack-2.4.0.0-64bit-zh_CN.msi 安装过程中不用填写、不用选择,全部点"下一步",完成后需要重启机器。 2、基本设…...
Python-闭包
介绍 Python的闭包是一种高级的编程技巧,它可以在函数内部定义另一个函数,并返回该函数的引用。这个内部函数可以访问外部函数的变量和参数,即使外部函数已经执行完毕 好处 1)闭包可以避免全局变量的污染,使得代码更…...
Gitlab中Pipeline语法四
Gitlab中Pipeline语法 cache cache:paths 在job build中定义缓存,将会缓存target目录下的所有*.jar文件当全局定义了cache:paths会被job中覆盖.以下实例将缓存target目录 buld:script: buildcache:paths:- target/*.jar#设置key可以解决cache被覆盖 cache:paths:- my/files…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
