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

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. Python3异常-AttributeError: module 'sys' has no attribute 'setdefaultencoding'

    基于python3.6.1版本,在一个.py文件中,加入这3行: import requests, re, sys reload(sys) sys.setdefaultencoding("u ...

  2. Frequent values(ST)

    描述 You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to ...

  3. PTA 10-排序6 Sort with Swap(0, i) (25分)

    题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/678 5-16 Sort with Swap(0, i)   (25分) Given a ...

  4. 在Ubuntu中,用mvn打包hadoop源代码时报错,正在解决中!!!

    报错信息如下: (各种配置在最后面) hadoop@administrator-virtual-machine:~/Downloads/tar/hadoop-3.0.0-alpha1-src$ mvn ...

  5. BZOJ-1798 维护序列

    线段树.支持区间加.区间乘.区间查询和. 标记下移还有取模要注意. var n,p,q,i,s,t:longint; a:int64; num,n1,n2,n3:array[0..500000] of ...

  6. NOIP2017赛前模拟(4):总结

    题目: 1.打牌 给定n个整数(n<=1000000),按照扑克牌对子(x,x)或者顺子(x,x+1,x+2)打出牌···问最多可以打出多少次对子或者顺子?牌的大小<=1000000 2. ...

  7. C# 图像旋转代码

    方法一: public static Bitmap rotateImage(Bitmap b, float angle) { //create a new empty bitmap to hold r ...

  8. C++基类与派生类的转换

    具体表现在以下几个方面: 派生类对象可以向基类对象赋值. 可以用子类(即公用派生类)对象对其基类对象赋值.如    A a1; //定义基类A对象a1    B b1; //定义类A的公用派生类B的对 ...

  9. FNV与FNV-1a Hash算法说明【转】

    转自:http://blog.csdn.net/jiayanhui2877/article/details/12090575 The core of the FNV hash The core of ...

  10. 标准C程序设计七---55

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...