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

Proxy 代理模式也是属于“接口隔离”模式,通过增加一层间接层来解决问题的模式。

文章目录

  • 1. 动机( Motivation)
  • 2. 模式定义
  • 3. 结构( Structure )
  • 4. 代码演示Proxy 代理模式
    • 4.1 常规方法
    • 4.2 Proxy 代理模式
  • 5. 要点总结
  • 6. 其他参考

1. 动机( Motivation)

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

  • 如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性?增加一层间接层是软件开发中常见的解决方式。
    所谓透明操作就是一致性,假如本来访问这个对象的方式是new一个对象,调用对象接口,那我还用类似方式访问你,至于背后的麻烦事,都不用知道,实现隔离。

2. 模式定义

为其他对象提供一种代理以控制(隔离,使用接口) 对这个对象的访问。
—《设计模式》GoF

3. 结构( Structure )

在这里插入图片描述
上图是《设计模式》GoF中定义的Proxy 代理模式的设计结构。结合上面的代码看图中最重要的是看其中稳定和变化部分,也就是下图中红框和蓝框框选的部分。
在这里插入图片描述

模式的结构很简单,但在实际使用过程中,可能会变得非常复杂。上图中接口为Subject,实际的对象为RealSubject,本来进行访问时,Client应该是直接声明一个Subject的接口,真正实际创建的是一个RealSubject的对象,但是由于某种特殊的原因,这时Client就应该直接去访问ProxyProxyRealSubject之间背后要做的事情很复杂。

4. 代码演示Proxy 代理模式

4.1 常规方法

以下是一个简单的示意性的例子,按照常规的做法,创建接口,RealSubject作为实际对象,ClientApp直接声明一个Subject的接口,真正实际创建的是一个RealSubject的对象。

client.cpp

//接口
class ISubject{
public:
    virtual void process();
};


class RealSubject: public ISubject{
public:
    virtual void process(){
        //....
    }
};

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

这种方式是不合适的,可能是由于性能、安全控制、分布式等原因,无法达到new RealSubject();此时应该怎么去做呢?

4.2 Proxy 代理模式

使用Proxy 代理模式模式的做法如下:

proxy.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.cpp有时候是自己写,有时候是使用工具生成的。创建接口class SubjectProxy: public ISubject,SubjectProxy实现一种对RealSubject的间接访问,在class ClientApp中创建subject=new SubjectProxy();SubjectProxy()针对RealSubject()的代理

Proxy 代理模式常常会设计的比较复杂,但是整体的设计思想要进行理解。

5. 要点总结

  • “增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。
  • 具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模块提供抽象代理层,在架构层次对对象做proxy。

具体到实际中,以下代码的差异度相当大,总体设计思想遵循:代理类(SubjectProxy)和实际类(RealSubject)的接口(ISubject)是一致的

    virtual void process(){
        //对RealSubject的一种间接访问
        //....
    }

copy-on-write技术:字符串类中经常如此去做,如果对象没有什么更改的话,复制的话,内部会生成一个指针指向原来的对象,每拷贝一次都是浅拷贝,这种共享在当你需要改这个对象时就是有问题的,此时你就需要内部拷贝一份,实现一种代理
在分布式系统中会大量使用Proxy 代理模式

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

代理的核心思想是增加一个中间层,实现不为外界所知的功能

6. 其他参考

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

How to install the console system of i-search rpa on Centos 7

How to install the console system of i-search rpa on Centos 7 1、 准备1.1 、查看磁盘分区状态1.2、上传文件1.2.1、添加上传目录1.2.2、上传安装包1.2.3、解压安装包1.2.4、查看安装包结构 1.3、安装依赖包1.3.1、基础依赖包1.3.2 相关依赖 1.4、关闭防火墙1.5、解除SeLin…

MyBaties存储和查询json格式的数据(实体存储查询版本)

最近在做的功能,由于别的数据库有值,需要这边的不同入口的进来查询,所以需要同步过来,如果再继续一个一个生成列对应处理感觉不方便,如果没有别的操作,只是存储和查询,那就可以用MySql支持的jso…

2022年上半年上午易错题(软件设计师考试)

1.以下关于冯诺依曼计算机的叙述中,不正确的是( )。 A.程序指令和数据都采用二进制表示 B.程序指令总是存储在主存中,而数据则存储在高速缓存中 C.程序的功能都由中央处理器(CPU)执行指令来实现 D.程序的执行过程由指令进行自动控制 程序指令和数据…

【Android】MQTT入门——服务器部署与客户端搭建

目录 MQTT 协议简介应用场景优点缺点 部署服务端下载安装包启动服务器 搭建客户端下载SDK添加依赖配置MQTT服务和权限建立连接订阅主题发布消息取消订阅断开连接 MQTT客户端工具最终效果实现传感器数据采集与监测功能思路 MQTT 协议 简介 MQTT(Message Queuing Te…

Mac 安装使用NPM及常用命令

环境: Mac 工具: NPM 可通过官网查询一些模块相关 NPM Doc 通过官网文档了解更多的关于NPM的使用 安装 NPM是Node.js的包管理工具,可用于解决 Node.js在代码部署上的问题。 新版本的Node.js已经集成了NPM, 因此可通过下载 Nod…

OpenCV C++ 图像处理实战 ——《缺陷检测》

OpenCV C++ 图像处理实战 ——《缺陷检测》 一、结果演示二、缺陷检测算法2.1、多元模板图像2.2、训练差异模型三、图像配准3.1 功能源码3.1 功能效果四、多元模板图像4.1 功能源码五、缺陷检测5.1 功能源码六、源码测试图像下载总结一、结果演示

Python爬虫基础之Requests详解

目录 1. 简介2. 安装3. 发送请求4. 处理响应5. IP代理6. Cookie登录参考文献 原文地址:https://program-park.top/2023/10/27/reptile_4/ 本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由…

【Unity3D】Unity与Android交互

1 Unity 发布 apk 1.1 安装 Android Build Support 在 Unity Hub 中打开添加模块窗口,操作如下。 选择 Android Build Support 安装,如下(笔者这里已安装过)。 创建一个 Unity 项目,依次点击【File→Build Settings→…

uniapp实现瀑布流

首先我们要先了解什么是瀑布流: 瀑布流(Waterfall Flow)是一种常见的网页布局方式,也被称为瀑布式布局或砌砖式布局。它通常用于展示图片、博客文章、商品等多个不同大小和高度的元素。 瀑布流布局的特点是每个元素按照从上到下…

制作自己的前端组件库并上传到npm上

最近实现了自己的一个前端组件库demo,目前只上传了几个小组件。话不多说,上图: 我分了三个项目:yt-ui组件库、使用文档、demo。线上地址如下: [yt-ui组件库](mhfwork/yt-ui - npm) [组件库使用文档](介绍 | mhfwork/y…

【Java 进阶篇】解决Java Web应用中请求参数中文乱码问题

在Java Web应用开发中,处理请求参数时经常会遇到中文乱码的问题。当浏览器向服务器发送包含中文字符的请求参数时,如果不正确处理,可能会导致乱码问题,使得参数无法正确解析和显示。本文将详细探讨Java Web应用中请求参数中文乱码…

安全狗安装

安装waf 关闭apache程序及httpd.exe进程; 运行cmd,cd进入apache/bin文件夹目录, 执行httpd.exe -k install -n apache2.4.39; 启动apache,启动phpstudy 安全狗安装服务名称填写apache2.4.39; 安装安全狗之后就会提示报错 IP黑白名单 可以设备黑白名单 …

本机spark 通idea连接Oracle的坑

1. 报错:Exception in thread "main" java.lang.NoSuchMethodError: scala.Product.$init$(Lscala/Product;)V 查询网上资料,是idea引入的scala运行环境版本与idea默认的scala版本不一样 也就是写的项目中的pom的spark版本与idea默认的版本不…

leetcode经典面试150题---4.删除有序数组中的重复项II

目录 题目描述 前置知识 代码 方法一 双指针 思路 图解 实现 复杂度 题目描述 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间&…

Ant Design Vue UI框架的基础使用,及通用后台管理模板的小demo【简单】

一、创建 VUE 项目 npm create vuelatest二、安装使用 ant-design-vue 安装脚手架工具 $ npm install -g vue/cli # OR $ yarn global add vue/cli使用组件 # 安装 $ npm i --save ant-design-vue4.x全局完整注册 import { createApp } from vue; import Antd from ant-de…

Ubuntu系统编译调试QGIS源码保姆级教程

在之前的文章中,我详细介绍了怎么在Windows下编译QGIS源码,也得到了不错的反馈。但是不足的是Windows下只能编译QGIS的Release模式和RelWithDebInfo模式,想要分析源码,“断点调试”肯定是少不了的,但是这两种模式虽然也…

hdlbits系列verilog解答(移位寄存器)-23

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 您将获得一个具有两个输入和一个输出的模块 my_dff (实现 D 触发器)。实例化其中的三个,然后将它们链接在一起以形成长度为 3 的移位寄存器。端口 clk 需要连接到所有实例。…

windows下基于vscode的ssh服务远程连接ubuntu服务器

Ubuntu端配置 1.确保ubuntu端已启用ssh服务 首先,安装ssh服务 sudo apt-get install openssh-server 安装后,打开ssh服务 sudo service ssh start 如果显示有sshd就说明成功了。 判断是否成功打开 ps -e|grep ssh 同时也可以通过如下方式确保ss…

docker 中给命令起别名

docker 的有些命令特别复杂,我们可以给它设置别名简化输入,就不用每次都输入那么多了!!! 1. 进入 .bashrc 中修改配置( .bashrc 是root下的隐藏文件) cd /rootvim .bashrc2. 在 .bashrc 中加入…

Java程序设计进阶

Java异常处理机制 异常 异常的最高父类是 Throwable,在 java.lang 包下。 Throwable 类的方法主要有: 方法说明public String getMessage()返回对象的错误信息public void printStackTrace()输出对象的跟踪信息到标准错误输出流public void printSta…