我所理解的设计模式(C++实现)——代理模式(Proxy Pattern)

Simulink Functions:从高级技巧到现代建模核心的范式转变 在基于模型的设计(MBD)和自动代码生成领域,模块化与接口清晰是提升软件组件可重用性和可维护性的关键。其核心原理在于通过定义明确的函数接口,将复杂算法封装为独立的可调用单元,从而实现控制逻辑与算法实现的解耦。这一技术价值在于它能显著提升模型架构的清晰度,并生成高质量、易于集成的嵌入式C/C++代码。在实际应用中,无论是四旋翼的滑模控制、模糊PID参数整定,还是结合ANN的MPPT算法,通过Simulink Functions进行封装,都能使模型从“能跑通”迈向“架构清晰、易于协作”的工业级水准,有效支撑汽车 阅读详情

概述

作为C++工程师,免不了要管理内存,内存管理也是C++中的难点,而智能指针采用引用计数的办法很方便的帮我们管理了内存的使用,极大方便了我们的工作效率。而智能指针的这种用法其实就是代理模式的一种,他帮我们控制了该对象的内存使用。

代理模式就是为其他对象提供一种代理来控制对这个对象的访问。


种类和用途

Proxy模式根据种类不同,效果也不尽相同:

1、远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的而不是远程的,而代理对象承担了大部份的网络通讯工作。由于客户可能没有意识到会启动一个耗费时间的远程调用,因此客户没有必要的思想准备。

2、虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。使用虚拟代理模式的好处就是代理对象可以在必要的时候才将被代理的对象加载;代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的情况下,虚拟代理的好处就非常明显。

3、Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。

4、保护(Protector Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。保护代理的好处是它可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。

5、Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

6、防火墙(Firewall)代理:保护目标,不让恶意用户接近。

7、同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。

8、智能引用(SmartReference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

在所有种类的代理模式中,虚拟(Virtual)代理、远程(Remote)代理、智能引用代理(SmartReference Proxy)和保护(Protector Access)代理是最为常见的代理模式。

 

类图和实例


代理模式所涉及的角色有:

抽象主题角色(Subject):声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题。

代理主题(Proxy)角色:代理主题角色内部含有对真是主题的引用,从而可以在任何时候操作真实主题对象;代理主题角色提供一个与真实主题角色相同的接口,以便可以在任何时候都可以替代真实主体;控制真实主题的应用,负责在需要的时候创建真实主题对象(和删除真实主题对象);代理角色通常在将客户端调用传递给真实的主题之前或之后,都要执行某个操作,而不是单纯的将调用传递给真实主题对象。

真实主题角色(RealSubject)角色:定义了代理角色所代表的真实对象。


这里给出一个C++中智能指针的例子,自己代码重新实现了下:

// TestProxy.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <assert.h>

#define KSAFE_DELETE(p) \
    if (p)			 \
        {				 \
        delete p;	 \
        p = NULL;	 \
        }

class KRefCount
{
public:
    KRefCount():m_nCount(0){}

public:
    void AddRef(){m_nCount++;}
    int Release(){return --m_nCount;}
    void Reset(){m_nCount=0;}

private:
    int m_nCount;
};

template <typename T>
class KSmartPtr
{
public:
    KSmartPtr(void)
        : m_pData(NULL)
    {
        m_pReference = new KRefCount();
        m_pReference->AddRef();
    }
    KSmartPtr(T* pValue)
        : m_pData(pValue)
    {
        m_pReference = new KRefCount();
        m_pReference->AddRef();
    }
    KSmartPtr(const KSmartPtr<T>& sp)
        : m_pData(sp.m_pData)
        , m_pReference(sp.m_pReference)
    {
        m_pReference->AddRef();
    }
    ~KSmartPtr(void)
    {
        if (m_pReference && m_pReference->Release() == 0)
        {
            KSAFE_DELETE(m_pData);
            KSAFE_DELETE(m_pReference);
        }
    }

    inline T& operator*()
    {
        return *m_pData;
    }
    inline T* operator->()
    {
        return m_pData;
    }
    KSmartPtr<T>& operator=(const KSmartPtr<T>& sp)
    {
        if (this != &sp)
        {
            if (m_pReference && m_pReference->Release() == 0)
            {
                KSAFE_DELETE(m_pData);
                KSAFE_DELETE(m_pReference);
            }

            m_pData = sp.m_pData;
            m_pReference = sp.m_pReference;
            m_pReference->AddRef();
        }

        return *this;
    }
    KSmartPtr<T>& operator=(T* pValue)
    {
        if (m_pReference && m_pReference->Release() == 0)
        {
            KSAFE_DELETE(m_pData);
            KSAFE_DELETE(m_pReference);
        }
        m_pData = pValue;
        m_pReference = new KRefCount;
        m_pReference->AddRef();

        return *this;
    }

    T* Get()
    {
        T* ptr = NULL;        
        ptr = m_pData;

        return ptr;
    }
    void Attach(T* pObject)
    {
        if (m_pReference->Release() == 0)
        {
            KSAFE_DELETE(m_pData);
            KSAFE_DELETE(m_pReference);
        }

        m_pData = pObject;
        m_pReference = new KRefCount;
        m_pReference->AddRef();
    }

    T* Detach()
    {
        T* ptr = NULL;

        if (m_pData)
        {           
            ptr = m_pData;
            m_pData = NULL;
            m_pReference->Reset();
        }
        return ptr;
    }

private:
    KRefCount* m_pReference;
    T* m_pData;
};

与其他模式的区别

1)适配器模式Adapter

适配器Adapter为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。

2) 装饰器模式Decorator

尽管Decorator的实现部分与代理相似,但Decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。 

总结

在软件系统中,加一个中间层是我们常用的解决方法,这方面Proxy模式给了我们很好的实现。


LCL_data原创于youkuaiyun.com【http://blog.youkuaiyun.com/lcl_data/article/details/8989420】


MATLAB及Simulink----基本知识简介 目前,MATLAB已成为国际上最为流行的科学计算与工程计算软件工具之一,如今的MATLAB已经不仅仅是矩阵运算或数值计算的软件,它已经发展成为一种具有广泛应用前景、全新的计算机高级编程语言,可以说它是“第四代”计算机语言。 自20世纪90年代,美国和欧洲的各个大学将MATLAB正式列入研究生和本科生的教材计划,MATLAB软件已经成为数值计算、数理统计、数字信号处理、自动控制、时间序列分析、动态系统仿真等课程的基本教学工具,成为学生必须掌握的基本软件之一。在研究单位和工业界,MATLAB也成为工程师们必须掌 阅读详情

相关推荐

Simulink模型保护实战:Protected Model、FMU与S-Function深度解析

在模型驱动开发与数字孪生领域,模型保护是确保知识产权和保障协作流程的关键技术。其核心原理是通过加密、编译或封装,将模型内部实现细节隐藏,仅暴露必要的输入输出接口,从而在交付、集成和联合仿真过程中防止核心算法与敏感参数被窥探或篡改。这项技术的核心价值在于平衡了知识共享与资产保护的需求,广泛应用于汽车电子、航空航天、工业控制等对算法保密性和模型可靠性要求极高的场景。具体到Simulink生态,工程师常面临如何安全交付模型给客户或供应商的挑战。为此,MathWorks提供了多种标准化方案,其中Protected

weixin_34248705的博客 380

【C语言】字符串转为十六进制(str_to_hex)

近日在开发过程中,遇到一个问题。将字符串转为十六进制,利用snprintf转换str的格式。 下面贴上代码实现。 #include <stdio.h> void test_printf5(char *str,int length) { int iii; printf("the str is:"); for(iii= 0;iii <length;iii++) { printf("%02x ",str[iii]); } printf("\n"); } /*str

NBDR_YL的博客 2万+

别再手动传数据了!用Python+Simulink的UDP通讯,5分钟搞定跨平台数据交互

本文详细介绍了如何利用Python和Simulink的UDP通信实现跨平台数据交互,解决工程仿真与数据分析中的效率瓶颈。通过实战指南,读者将掌握UDP通信的低延迟优势、Simulink配置步骤及Python实现方案,适用于实时数据传输和可视化系统开发。

weixin_33720956的博客 263

设计模式之代理模式(C++)

介绍设计模式之代理模式

翟天保的博客 2万+

Vitis Model Composer:从Simulink算法模型到FPGA硬件IP的高效实现

高层次综合(HLS)技术是连接算法设计与硬件实现的关键桥梁,它允许开发者使用高级抽象语言或图形化工具描述系统行为,并自动转换为可综合的寄存器传输级(RTL)代码。其核心原理在于通过编译器技术对行为级描述进行调度、绑定和优化,生成高效的硬件电路。这项技术的价值在于大幅缩短了从算法原型到硬件部署的开发周期,降低了硬件开发门槛,尤其适用于通信、图像处理、电机控制和人工智能推理加速等对实时性和能效要求高的领域。在FPGA开发中,Vitis Model Composer正是这一理念的杰出实践,它深度集成于Simuli

weixin_33889245的博客 479

MATLAB SIMULINK中的PI控制器模型设计与实现

在自动化控制领域,PI(比例-积分)控制器是常见的反馈控制器之一,具有广泛的应用。PI控制器通过比例和积分两种控制作用,调整系统的输出,以达到对某个量(如温度、速度、压力等)进行精确控制的目的。SIMULINK界面的设计旨在使模型设计变得更加直观和高效。主要的界面元素包括:模型浏览器(Model Explorer):用于查看和管理模型中的所有元素。库浏览器(Library Browser):提供了广泛的可拖拽模块和子系统,供用户快速构建模型。模型画布(Canvas)

weixin_42433737的博客 2381

【Proxy模式】C++设计模式——代理模式

C++代理模式,Proxy模式,本文以现实社会例子来阐述该模式,通过对代理模式的概括、总结、代码对比分析来帮助读者了解该模式

不负AC不负卿的博客 2845

MATLAB Simulink中的增量式PID控制器设计

增量式PID(Proportional-Integral-Derivative)控制器是一种广泛应用于工业控制系统的反馈回路控制器。它通过计算偏差值或误差值的比例、积分和微分来调节控制量,以达到控制目的。在增量式实现中,控制器只输出对控制量的增量变化,而不是直接输出控制量。MATLAB(Matrix Laboratory)是一个高性能的数值计算环境和第四代编程语言,广泛应用于工程计算、数据分析、算法开发等领域。MATLAB的基本界面主要分为以下几个部分:命令窗口。

weixin_42515340的博客 2080

C++之代理模式

对设计模式中的 代理模式进行了总结。

flyingcloud6的博客 1470

MATLAB中Simulink流程图开发指南

MATLAB与Simulink是MathWorks公司开发的两个强大的数学计算和仿真工具,它们在科学研究、工程设计、数据分析等领域发挥着重要作用。MATLAB是一种编程语言和交互式环境,用于算法开发、数据可视化、数据分析和数值计算,而Simulink则是在MATLAB环境下的一个动态系统模拟和模型设计工具。MATLAB的核心是其数学核心库,它提供了强大的矩阵计算能力和绘图功能。这使得它成为处理数学问题和数据可视化的理想选择。而Simulink则在图形化的用户界面上构建模型,模拟动态系统的行为。

weixin_42603332的博客 778

MATLAB系统建模与Simulink实践教程

在MATLAB中,函数是组织代码和实现算法重用性的基础。函数可以是独立的脚本文件,也可以嵌入到更大的脚本或函数中。MATLAB函数的基本结构包括函数名、输入参数(input arguments)、输出参数(output arguments)和函数体。定义MATLAB函数的通用格式如下:% 函数体endmyfunction是函数的名字。是输出参数,可以有一个或多个。是输入参数,同样可以有一个或多个。是执行具体计算任务的代码块。

weixin_42603332的博客 622

simulink入门学习02---基本算法

1.单位阶跃测试输入 2.模块重命名 3.对于信号的重命名 4.显示信号输出瞬时值 4.1display模块 4.2scope模块 4.3双击可视化 5.添加输入比较信号 5.1如何操作 5.2可视化比较 6.添加图例和标签 6.1添加标签 6.2添加图例 7.数学运算符 7.1信号函数的平方根 7.2常量源信号 7.3多信号处理subtract模块 7.4Gain模块放大信号 8.基本逻辑 8.1布尔比较 8.2信号与常量的比较 8.3逻辑运算符AND 9.条件语句 9.1switch模块 9.2分支处理

大学成长道路上的探索经历与点滴思考,与君共勉,共筑成长。 2044

MATLAB/Simulink光伏并网仿真项目:详细版2017a

MATLAB(Matrix Laboratory)是一种高性能的数值计算和可视化软件,最初由Cleve Moler教授在1980年代初开发,其后由MathWorks公司推向市场。它集成了数值分析、矩阵计算、信号处理和图形显示等功能,在工程计算、控制系统设计、数据分析等领域得到广泛应用。MATLAB提供了易于使用的高级编程语言,用户可以利用这些语言编写自定义函数和脚本。

weixin_29009401的博客 865

Simulink利用C代码开发S函数的编程环境搭建

Simulink中想用S-Function开发组件有4种编程语言,分别是c、c++、matlab语言、fortran。本文讲述如何搭建c、c++编译环境。

qq_46145354的博客 1493

allegro转AD-(附工具)

本文介绍了将Allegro的.brd文件转换为Altium Designer可用的.alg文件的操作流程。首先需要下载专用转换工具,然后通过运行.bat脚本将.brd文件转换为.alg格式。最后在Altium Designer中使用导入向导完成文件转换,生成可用的PCB设计文件。整个过程简单快捷,只需三个步骤即可实现Allegro到Altium Designer的工程文件转换。

weixin_50120208的博客 1713

“挑战杯”大赛“揭榜挂帅”赛道-baseline解析

在这个脚本中,txt文件的保存路径为'yolov7/datasets/Fatigue_driving_detection/txt_labels/',而xml文件的路径为'./label_xml/'。标注图片后的产物是会给每一个图片对应生成一个xml格式的文件,但是如果要用yolo框架去训练模型,输入的数据必须是txt格式,因此这里有一步转换格式的过程。注意看:obs这里有三个文件夹,第一个是关键帧的文件夹A,第二个是标注时输出的位置为文件夹B,第三个是智能标注后和手动标注的合集文件夹C。

m0_62899814的博客 2321

simulink中调用C语言:C-Script

使用Simulink自带的S function模块和PLECS嵌入版中的C-Script模块两者均可快速实现在simulink中调用C语言。其中C-Script更易上手,就该方法简短介绍。

qq_42059684的博客 3354

电感损耗 DCR/ACR/磁芯损耗 3 大来源解析:从集肤效应到磁滞回线

本文深入解析电感损耗的三大来源:DCR(直流电阻)、ACR(交流电阻)和磁芯损耗,从集肤效应到磁滞回线的微观机制。通过对比不同材料和设计策略,提供高频开关电源中电感损耗的优化方案,帮助工程师提升系统效率和可靠性。

weixin_34379433的博客 512

别再死记公式了!用Simulink Prelookup模块的k和f,手把手教你搞定一维插值

本文通过Simulink Prelookup模块的k和f参数,详细讲解一维插值的实战应用,帮助工程师摆脱公式记忆。文章涵盖断点设置、参数解析及常见误区,提供完整的验证模型搭建步骤和高级应用技巧,助力提升工程建模效率。

weixin_30342209的博客 249

高分系列卫星轨道、传感器参数等信息

遥感卫星数据简介-高分系列

中遥科 3309

Cadence导入tsmcN65GP PDK的完整流程与常见问题解析

本文详细介绍了Cadence导入tsmcN65GP PDK的完整流程,包括文件解压、目录结构解析、安装脚本运行及Cadence集成配置。重点解析了常见问题如文件路径错误、权限问题和工艺库显示不全的解决方案,并提供了实战技巧与优化建议,帮助用户高效完成PDK安装与配置。

weixin_29215391的博客 546

Simulink与C语言深度集成:C-Script模块实战指南

本文详细介绍了Simulink中C-Script模块的实战应用,通过六层代码结构解析和电力电子控制实例,展示了如何实现C语言算法与Simulink仿真的深度集成。重点探讨了C-Script在嵌入式代码移植、开发效率和调试维护方面的优势,为工程师提供了从仿真验证到嵌入式部署的完整解决方案。

h0i1j2k3l的博客 65

MNI152 坐标空间和 fsaverage 坐标空间相互转换, 如已知fsaverage空间的坐标如何求MNI152 坐标?aparc.a2009s.annot转化到MNI152空间?

大多数神经影像学研究的结果是在体积(例如,MNI152)或表面(例如,fsaverage)坐标系中报告的。体积坐标系和表面坐标系之间的准确映射可以促进许多应用,例如将 fMRI 组分析从 MNI152 投影到 fsaverage 以进行可视化或从 fsaverage 投影静息状态 fMRI 分区对 MNI152进行新数据的体积分析。Wu et al., 2018 评估了三种在 MNI152通过模拟上述应用的 Colin27 和 fsaverage 坐标系:将组平均数据从 MNI152/Colin27 投影到

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 2965
上一篇: 我所理解的设计模式(C++实现)——享元模式(Flyweight Pattern)
下一篇: 我所理解的设计模式(C++实现)——责任链模式(Chain Of Responsibility Pattern)
十八道胡同
博客等级 码龄20年 848粉丝 109原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值