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

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. Selenium WebDriver-actionchain模拟鼠标右键操作

    #encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...

  2. Leetcode 448.找到所有数组中消失的数字

    找到所有数组中消失的数字 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次. 找到所有在 [1, n] 范围之间没有出现 ...

  3. 递归函数的写法(以strcpy函数为例)

    1. 递归函数模板 递归的前提是,找到一个公共子问题(或公共操作),然后将该函数构造为递归函数. retType function( ... ) { 结束条件 { [处理] 返回 } 递归条件 { [ ...

  4. [译]pandas中的iloc loc的区别?

    loc 从特定的 gets rows (or columns) with particular labels from the index. iloc gets rows (or columns) a ...

  5. javascript学习笔记 - 引用类型 RegExp

    四 RegExp 格式: var expression = / pattern / flags; 1.flags 为标志.分别为g.i.m. g:表示全局模式.即模式将匹配所有的字符串,而不是在发现第 ...

  6. 使用jackson解析JSON数据

    本文介绍使用jackson来对json数据进行解析操作 首先,需要去官网下载jackson,本文使用的是(jackson-all-1.9.11.jar) 主要通过ObjectMapper对json进行 ...

  7. HDU——1042N!(大数阶乘乘法)

    N! Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Subm ...

  8. BZOJ 3489 A simple rmq problem ——KD-Tree

    考前写写板子. 用$(i,pre[i],nxt[i])$来描述一个点,然后就变成了区间求最值的问题. KD-Tree 由低维转向高维的方法,可以用来敲暴力. 剩下就是KD-Tree的基本操作了. #i ...

  9. Python tldextract模块准确获取域名和后缀

    Python tldextract 模块 - 功能说明 tldextract准确地从URL的域名和子域名分离通用顶级域名或国家顶级域名. 例如,http://www.google.com,你只想取出连 ...

  10. QBXT 二月五号整理

    给你一列数, 询问和最大的子串. N<=10^6 // N <=10^6 #include<cstdio> #include<iostream> using nam ...