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

文章结束给大家来个程序员笑话:[M]

    

概述

    作为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原创于CSDN.NET【http://blog.csdn.net/lcl_data/article/details/8989420】

文章结束给大家分享下程序员的一些笑话语录: 腾讯的动作好快,2010年3月5日19时28分58秒,QQ同时在线人数1亿!刚刚看到编辑发布的文章,相差才2分钟,然后连专题页面都做出来了,他们早就预料到了吧?(其实,每人赠送10Q币,轻轻松松上两亿!)

--------------------------------- 原创文章 By
代理和对象
---------------------------------

转载于:https://www.cnblogs.com/xinyuyuanm/archive/2013/05/29/3106808.html

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

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

相关文章

android 自定义控件

自定义一般分三种情况 1. 自定义布局 2. 自定义控件 3.直接继承View 下面来着eoe例子&#xff0c;实现自定义控件 1. 自定义属性 res/values/attrs.xml 自定义属性 <?xml version"1.0" encoding"utf-8"?> <resources><declare-styleable …

Office文档模型深入---Outlook文档模型与开发实战(1)

简介 本篇为Office文档模型深入系列第4篇&#xff0c;原计划是Excel的图表&#xff0c;之后是Word&#xff0c;因为项目转手需要总结Outlook&#xff0c;先改变下顺序&#xff0c;后面的内容会慢慢补上。本篇为Outlook子系列的第一篇&#xff0c;主要介绍下outlook命名空间下…

写一个js向左滑动删除 交互特效的插件——Html5 touchmove

需求描述 需要实现类似QQ中对联系人的操作&#xff1a;向左滑动&#xff0c;滑出删除按钮。滑动超过一半时松开则自动滑到底&#xff0c;不到一半时松开则返回原处。 纯js实现 使用了h5的touchmove等事件&#xff0c;以及用js动态改变css3的translate属性来达到动画效果&#x…

Android----Fragments详解

Fragments 概念是在Android3.0版本就已经有了&#xff0c;3.0版本是Tab(平板)专用&#xff0c;后来在4.0以上的版本继续沿 用Fragments&#xff0c;改善了Activity的灵活性。 在没有Fragments之前&#xff0c;一个屏幕就只能放一个Activity&#xff0c;有了Fragments之后&#…

Hadoop Mapreduce分区、分组、二次排序过程详解

2019独角兽企业重金招聘Python工程师标准>>> 1、MapReduce中数据流动 &#xff08;1&#xff09;最简单的过程&#xff1a; map - reduce &#xff08;2&#xff09;定制了partitioner以将map的结果送往指定reducer的过程&#xff1a; map - partition - redu…

基于 OpenFire 的TVBox管理平台开发笔记

目录 一、開發環境設置.... 3 1.1 JDK 安裝.... 3 1.2 MySql Server安裝.... 4 1.3 OpenFire安裝.... 6 1.4 Openfire Admin 功能.... 14 1.4.1 用戶摘要&#xff1a;.... 16 1.4.2 組摘要&#xff1a;.... 16 1.4.3 用戶組管理&#xff1a;.... 17 1.4.4 發送管理消息&#xf…

IIS错误与解决方法

转载于:https://www.cnblogs.com/NFFF/archive/2013/06/03/IIS%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%94%99%e8%af%af%e4%b8%8e%e8%a7%a3%e5%86%b3%e6%96%b9%e6%b3%95.html

最大后验估计_PR Ⅱ:贝叶斯估计/推断及其与MAP的区别

Probabilistic in Robotics Ⅱ: Bayesian Estimation/Inference统计推断旨在根据可观察到的事物来了解不可观察到的事物。即&#xff0c;统计推断是基于一个总体或一些样本中的某些观察变量&#xff08;通常是影响&#xff09;得出结论的过程&#xff0c;例如关于总体或样本中某…

深入理解并行编程-分割和同步设计(四)

原文链接 作者&#xff1a;paul 译者&#xff1a;谢宝友&#xff0c;鲁阳&#xff0c;陈渝 图1.1&#xff1a;设计模式与锁粒度 图1.1是不同程度同步粒度的图形表示。每一种同步粒度都用一节内容来描述。下面几节主要关注锁&#xff0c;不过其他几种同步方式也有类似的粒…

string类的实现(构造函数,析构函数,运算符重载)

String类的代码&#xff1a;class String { public:String(char* str""){_str new char[strlen(str) 1];strcpy(_str, str);}String(const String& str){_str new char[strlen(str._str) 1];strcpy(_str, str._str);}~String(){delete[] _str;}String& o…

html网页设计一个简单的用户登录页面

结果 代码 login.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>用户登录页面</title><link rel"stylesheet" href"./css/login.css"><script src"j…

ip聚合简介

练习一 本题选择&#xff1a;D 解释如下&#xff1a; 人事部 205.67.159.1110 0000 /27 培训部 205.67.159.1101 0000 /28 销售部 205.67.159.1100 0000 /28 先是培训部与销售部做IP聚合&#xff08;只有网络前缀位数相同才可以做ip聚合&#xff09; 保留相同的位数&…

微信公众平台消息接口开发(34)桃花运测试

微信公众平台开发 微信公众平台开发者 微信公众平台开发模式 桃花运 作者&#xff1a;方倍工作室 原文&#xff1a;http://www.cnblogs.com/txw1958/archive/2013/06/06/weixin-if34-peach-blossom-luck.html 桃花运&#xff0c;一般指得到异性缘的运气。而这种运气又常常蕴涵在…

sharepoint 2013 个人站点母版

最近做了个项目&#xff0c;&#xff0c;sharepoint 个人站点要求定制&#xff0c;&#xff0c;搞了好久不知引用的模板 在何位置&#xff0c;查了好多资料还是没有办法解决&#xff0c;&#xff0c;经过不懈的努力&#xff0c;终于找到了&#xff0c;现在记录下&#xff0c;做…

telnet不是内部或外部命令解决方法

在使用window系统在使用telnet命令时&#xff0c;会出现“telnet不是内部或外部命令”的错误。 这是因为windows默认没有开启telnet client 开启window的telnet客户端功能&#xff0c;命令就可以使用了。 1.打开控制面板 2.选择程序 3.选择启用或关闭windows功能 4.将telnet…

C# 自定义箭头组件

C#自定义箭头组件&#xff0c;效果如图&#xff1a; 实现的功能&#xff1a; 1&#xff09; 箭头方向属性左、右、上、下&#xff1b; 2&#xff09; 颜色渐变&#xff0c;且颜色任意调整&#xff1b; 3&#xff09; 箭头大小位置任意调整&#xff1b; 4&#xff09; 其他。 主…

Android的debug.keystore拒绝访问导致的生成异常及解决方案

为什么80%的码农都做不了架构师&#xff1f;>>> 构建Android应用程序的时候输出异常:[apkbuilder] keytool 错误: java.io.FileNotFoundException: C:\Users\my\.android\debug.keystore(拒绝访问.) 导致BUILD FAILED. ##异常原因: Android要求所有的应用程序必须有…

C语言猜数字游戏

程序代码 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h> #include<windows.h> #include<stdlib.h> #include<time.h> void menu() {printf("***********************\n");printf("** …

动态代理,动态代理设计模式 ,JDK动态代理,cglib动态代理

为什么80%的码农都做不了架构师&#xff1f;>>> 一&#xff1a;在看此篇代码示例前&#xff0c;先看静态代理&#xff0c; 链接地址&#xff1a;http://my.oschina.net/dyyweb/blog/656760 &#xff08;代码示例&#xff09; 二&#xff1a;JDK动态代理 动态…

C语言扫雷游戏简单实现

文章目录前言一、代码思路二、代码实现1.引入库2.具体代码见以下链接&#xff0c;免费下载&#xff0c;无需慌张3.运行结果前言 本篇文章为使用C语言的easyX库函数实现扫雷小游戏 一、代码思路 1.设置扫雷地图 用一个二维数组表示扫雷地图 初始化二维数组 埋雷&#xff0c;-1…