代理模式:为其它对象提供一种代理以控制对这个对象的訪问。

Proxy:



保存一个引用使得代理能够訪问实体。若RealSubject和Subject的接口同样,Proxy会引用Subject,就相当于在代理类中保存一个Subject指针。该指针会指向RealSubject。

提供一个与Subject的接口同样的接口,这样代理就能够用来替代实体。

控制对实体的存取。并可能负责创建和删除它;

其他功能依赖于代理的类型,比如:

远程代理负责对请求及其參数进行编码,并向不同地址空间中的实体发送已编码的请求;

虚代理能够缓存实体的附加信息,以便延迟对它的訪问。

保护代理检查调用者是否具有实现一个请求所必须的訪问权限。



Subject:定义RealSubject和Proxy的共用接口。这样就在不论什么使用RealSubject的地方都能够使用Proxy;



RealSubject:定义Proxy所代理的实体。

1、远程代理为一个对象在不同的地址空间提供局部代理;

2、虚代理依据需求创建开销非常大的对象。

3、保护代理控制原始对象的訪问;保护代理用于对象应该有不同的訪问权限的时候;

4、智能引用代替了简单的指针,它在訪问对象时运行一些附加操作。它的典型用途包含:

       对指向实际对象的引用计数,这样当该对象没有引用时,能够自己主动释放它;

引用计数智能指针:

#include <iostream>
#include <windows.h>
using namespace std; #define SAFE_DELETE(p) if (p) { delete p; p = NULL; } class KRefCount
{
public:
KRefCount():m_nCount(0){} public:
unsigned AddRef(){ return InterlockedIncrement(&m_nCount); }
unsigned Release(){ return InterlockedDecrement(&m_nCount); }
void Reset(){ m_nCount = 0; } private:
unsigned long m_nCount;
}; template <typename T>
class SmartPtr
{
public:
SmartPtr(void)
: m_pData(NULL)
{
m_pReference = new KRefCount();
m_pReference->AddRef();
} SmartPtr(T* pValue)
: m_pData(pValue)
{
m_pReference = new KRefCount();
m_pReference->AddRef();
} SmartPtr(const SmartPtr<T>& sp)
: m_pData(sp.m_pData)
, m_pReference(sp.m_pReference)
{
m_pReference->AddRef();
} ~SmartPtr(void)
{
if (m_pReference && m_pReference->Release() == 0)
{
SAFE_DELETE(m_pData);
SAFE_DELETE(m_pReference);
}
} inline T& operator*()
{
return *m_pData;
} inline T* operator->()
{
return m_pData;
} SmartPtr<T>& operator=(const SmartPtr<T>& sp)
{
if (this != &sp)
{
if (m_pReference && m_pReference->Release() == 0)
{
SAFE_DELETE(m_pData);
SAFE_DELETE(m_pReference);
} m_pData = sp.m_pData;
m_pReference = sp.m_pReference;
m_pReference->AddRef();
} return *this;
} SmartPtr<T>& operator=(T* pValue)
{
if (m_pReference && m_pReference->Release() == 0)
{
SAFE_DELETE(m_pData);
SAFE_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)
{
SAFE_DELETE(m_pData);
SAFE_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;
}; class CTest
{
public:
CTest(int b) : a(b) {}
private:
int a;
}; int main()
{
SmartPtr<CTest> pSmartPtr1(new CTest(10));
SmartPtr<CTest> pSmartPtr2(new CTest(20)); pSmartPtr1 = pSmartPtr2;
}

智能指针使用引用计数实现时,就是最好的使用代理模式的样例。在上面的样例中,SmartPtr就是一个代理类。而T* m_pData才是实际的数据。

SmartPtr代理实际的数据,去实现了指针的行为。加入了引用计数,从而实现了智能指针。

[C++设计模式] proxy 代理模式的更多相关文章

  1. C++设计模式-Proxy代理模式

    Proxy代理模式 作用:为其他对象提供一种代理以控制对这个对象的访问. 代理的种类: 如果按照使用目的来划分,代理有以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代 ...

  2. php设计模式 Proxy (代理模式)

    代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,都是通过代理来完成他的销售业务.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行 ...

  3. 设计模式——proxy代理模式

    目录 概述 定义 角色 为什么会有代理模式? 应用场景 示例 静态代理 例子 动态代理 JDK中生成代理对象的API 代码示例: 代码示例2 Cglib代理 代码示例 AOP(AspectOrient ...

  4. C#设计模式(13)——代理模式(Proxy Pattern)

    一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代 ...

  5. php设计模式之Proxy(代理模式)和Facade(外观)设计模式

    Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对 ...

  6. java设计模式之Proxy(代理模式)

    java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...

  7. 乐在其中设计模式(C#) - 代理模式(Proxy Pattern)

    原文:乐在其中设计模式(C#) - 代理模式(Proxy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 代理模式(Proxy Pattern) 作者:webabcd 介绍 为 ...

  8. 设计模式之代理模式之二(Proxy)

    from://http://www.cnblogs.com/xwdreamer/archive/2012/05/23/2515306.html 设计模式之代理模式之二(Proxy)   0.前言 在前 ...

  9. 设计模式12: Proxy 代理模式(结构型模式)

    Proxy 代理模式(结构型模式) 直接与间接 人们对于复杂的软件系统常常有一种处理手法,即增加一层间接层,从而对系统获得一种更为灵活.满足特定需求的解决方案.如下图,开始时,A需要和B进行3次通信, ...

随机推荐

  1. maya 2014帮助手册中 三维概念讲解

    maya 2014 帮助手册中   三维概念讲解 多边形简介 三个或更多的边,   顶点    边    面  组成 经常使用三边形或四边形来建模   n边形不常用 单个多边形称为面   多个面连接到 ...

  2. c3p0数据库连接池无法连接数据库—错误使用了username关键字

    一.问题描述 上篇博客说到了关于maven无法下载依赖jar包的问题,这篇博客再说一下关于在本个项目中遇到的关于使用C3P0连接池连接数据库的问题,真心很奇葩,在此,也请大家引起注意.首先看我的项目基 ...

  3. SPFA ----模板 O(kE) (k一般不超过2)

    原理:若一个点入队的次数超过顶点数V,则存在负环: #include "bits/stdc++.h" using namespace std; ; struct Edge { in ...

  4. curl post 用json方式

    if(!function_exists('tps_curl_post3')){ function tps_curl_post3($url, $postData) { $postData = json_ ...

  5. 【Luogu】P3704数字表格(莫比乌斯反演+大胆暴力)

    题目链接 给你们讲个笑话:Konoset是个sb,他快速幂的时候把幂次取模了. 原式差不多就是这样吧$\prod\limits_{i=1}^{n}\prod\limits_{j=1}^{m}f[gcd ...

  6. IE7下li超出ul的固定宽度后溢出bug

    问题描述: ul固定宽度,li浮动超出ul的宽度自动换行,li有左margin,但是靠近ul左边缘的那一列l 的margin设为0,其他浏览器正常,但是在ie7中超出ul宽度后会有一个l溢出并导致出现 ...

  7. 如何查找Windows上安装的DB2的端口号Port

    1.db2com打开控制台 2.db2 get dbm cfg 可以通过db2 get dbm cfg,查询数据库管理器配置参数,就可以查到端口号或端口名. 示例: $ db2 get dbm cfg ...

  8. [TJOI2017] 城市 (树的直径,贪心)

    题目链接 Solution 这道题,调了我一晚上... 一直80分 >_<|| ... 考虑到几点: 分开任意一条边 \(u\) ,那么其肯定会断成两棵树. 肯定是分开直径上的边最优,否则 ...

  9. JDBC链接mysql,时间时0000-00-00 00:00:00时报错

    应为mysql默认最小timestamp是0001-01-01 00:00:00,所以查询出来会报错 需要加在链接的url中加入 &zeroDateTimeBehavior=convertTo ...

  10. python中的 __xxx__ 方法

    1 __class__ instance.__class__ The class to which a class instance belongs def foo(): pass class A(o ...