首页 > 代码库 > 设计模式之十二:Proxy(代理)—对象结构型模式
设计模式之十二:Proxy(代理)—对象结构型模式
2014-05-29 星期四 21:08:37
Proxy,继续GOF。此模式未按GOF编写。
c++中使用StringBuilder
1、Intent
Provide a surrogate or placeholder for another object to control access to it.
为其他对象提供一种代理以控制对这个对象的访问。
2、Also Known As
3、Motivation
4、Applicability
在以下情况使用适配模式:
● 创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成,GoF称之为虚代理(Virtual Proxy)。?
● 为网络上的对象创建一个局部的本地代理,比如要操作一个网络上的一个对象(网络性能不好的时候,问题尤其突出),我们将这个操纵的过程交给一个代理去完成,GoF称之为远程代理(Remote Proxy)。
● 对对象进行控制访问的时候,比如在Jive论坛中不同权限的用户(如管理员、普通用户等)将获得不同层次的操作权限,我们将这个工作交给一个代理去完成,GoF称之为保护代理(ProtectionProxy)。
●智能指针(Smart Pointer),关于这个方面的内容,建议参看Andrew Koenig的《C++沉思录》中的第5章。
5、Structure
?
6、代码
Proxy模式最大的好处就是实现了逻辑和实现的彻底解耦。
?智能指针的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | // 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 = http://www.mamicode.com/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 = http://www.mamicode.com/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 = http://www.mamicode.com/pObject; m_pReference = new KRefCount; m_pReference->AddRef(); } T* Detach() { T* ptr = NULL; if (m_pData) { ptr = m_pData; m_pData = http://www.mamicode.com/NULL; m_pReference->Reset(); } return ptr; } private : KRefCount* m_pReference; T* m_pData; }; |
7、与其他模式的区别
● 适配器模式Adapter
适配器Adapter为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。
● 装饰器模式Decorator
尽管Decorator的实现部分与代理相似,但Decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。