当前位置: 首页 > news >正文

结构型模式--Proxy代理模式

 代理模式简介:

客户端通过代理对象来访问实际的服务对象。代理控制着客户端对服务对象的访问,可以在发送请求给服务对象的前后进行自定义处理。代理类和服务类应都实现自同一个接口,这样既可以在不改变客户端和服务器端代码的情况下增加新的代理类,同时对客户端来说不必关心访问的到底是服务器还是代理。

代理模式适合的部分应用场景(即代理模式的类型):

1. 保护代理

实现访问控制功能,如果希望只有拥有权限的客户对象才可以使用服务对象,就可以使用此模式。比如访问系统的操作日志,客户对象为普通用户,通过代理对象进行操作,代理判断权限不足不提供服务。当然访问控制也可以在服务端进行实现,如果服务端是不开放源代码的第三方库,那么就可以要代理模式。

2. 远程代理

适用于服务对象在远程服务器上的情况,代理通过网络传递客户请求,对客户端屏蔽一系列复杂的操作(例如请求封包解包、数据解析等)。对客户端来说和调用本地服务对象的过程相同。

3. 日志记录代理

适用于当需要保存对于服务对象的请求历史记录时。 代理可以在向服务传递请求前进行记录。

4. 虚拟代理

如果有一个偶尔使用的重量级服务对象, 一直保持该对象运行会消耗系统资源时, 可使用代理模式。无需在程序启动时就创建该对象, 可将对象的初始化延迟到真正有需要的时候。

代理模式的优点

1. 可以在客户端毫无察觉的情况下控制服务对象

2. 可以对服务对象的生命周期进行管理(如果客户端对服务对象的声明周期没有特殊要求)

3. 代理可以在服务对象还未创建的时候就开始工作

4. 可以在不对服务类或客户端类做出修改的情况下创建新的代理类

代理模式的缺点:

1. 服务响应可能会出现延迟

2. 代码可能会变得稍微复杂一些,因为要多创建一些类

保护代理的示例代码:

#include <iostream>

using namespace std;

//公共接口
class IServer 
{
public:
    virtual void doWork()=0;
};

//服务类
class RealServer :public IServer 
{
public:
    void doWork() { cout << "real_server work." << endl; }
};

//代理类
class Proxy :public IServer
{
public:
    Proxy(RealServer* server) :_server(new RealServer(*server)){    }

    bool checkAccess() const {
        cout << "check access.\n";
        return true;
    }

    void doWork() { 
        /*服务对象调用之前的控制操作,例如访问控制*/
        if (checkAccess()) {
            /* 委托给服务对象 */
            _server->doWork();
        }
    }
private:
    RealServer*_server;
};

//客户端调用代码
void clientInvoke(IServer* server)
{
    server->doWork();
}

int main()
{
    RealServer* real_server = new RealServer();
    clientInvoke(real_server);

    Proxy* proxy = new Proxy(real_server);
    clientInvoke(proxy);
}

相关文章:

  • C++的Lambda表达式的用法
  • 微信小程序学习之rich-text的嵌入静态HTML
  • 微信小程序CSS Flexbox(弹性盒子)布局模块
  • 语义化版本 2.0.0 -- 如何使用软件版本号
  • 微信小程序css之盒子(box)模型
  • 微信小程序中text标签换行问题
  • 微信小程序无法找到组件的问题 [“usingComponents“][“component1“]:“xxx“未找到
  • git本地仓库新建分支并推送到远端仓库
  • 微信小程序将组件中的文字放置在正中间的方法
  • linux脚本开头的#!/bin/bash有什么作用
  • git如何撤销未提交的更改
  • Qt动态更改界面语言(在运行状态下改变界面语言)
  • .gitignore文件---让git自动忽略指定文件
  • 解决QMYSQL driver not loaded问题
  • 信息安全之对称加密技术
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • Mocha测试初探
  • spring boot下thymeleaf全局静态变量配置
  • Spring核心 Bean的高级装配
  • 动态魔术使用DBMS_SQL
  • 服务器之间,相同帐号,实现免密钥登录
  • 开源SQL-on-Hadoop系统一览
  • 世界上最简单的无等待算法(getAndIncrement)
  • 译米田引理
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 自制字幕遮挡器
  • AI算硅基生命吗,为什么?
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #HarmonyOS:Web组件的使用
  • #前后端分离# 头条发布系统
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (¥1011)-(一千零一拾一元整)输出
  • (4)STL算法之比较
  • (C语言)fread与fwrite详解
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (vue)页面文件上传获取:action地址
  • (备忘)Java Map 遍历
  • (二)JAVA使用POI操作excel
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (一一四)第九章编程练习
  • .NET单元测试
  • .考试倒计时43天!来提分啦!
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [.net] 如何在mail的加入正文显示图片
  • [BZOJ5250][九省联考2018]秘密袭击(DP)
  • [C++数据结构](31)哈夫曼树,哈夫曼编码与解码
  • [Flex] PopUpButton系列 —— 控制弹出菜单的透明度、可用、可选择状态
  • [leetcode] Balanced Binary Tree
  • [Mac软件]Boxy SVG 4.20.0 矢量图形编辑器
  • [python]bar_chart_race设置日期格式
  • [SharePoint][SharePoint Designer 入门经典]Chapter13 客户端Silverlight编程