2016-07-18
(www.cnblogs.com/icmzn)
模式理解
1. Proxy 代理模式
为其他对象提供一种代理可以间接控制这个对象的访问。
又称为“委托模式”,其他设计模式也是在代理模式的基础上扩展的,如“策略模式”“状态模式”“访问者模式”,代理模式的特殊应用。
在Spring的AOP技术,以及Struts的From元素映射就是代理行为。
一般代理具有多种版本(扩展)如:普通代理模式,强制代理模式,动态代理模式
一般代理的角色:
(1)CAbsSubject: 抽象对象,被代理对象的一类的行为,抽象类或者接口。
(2)Proxy: 代理类,通过组合的方式(has a)拥有一个CabsSubject的指针或者引用,通过将抽象类的接口调用委托被真实对象实现,
从而可以通过代理控制真实对对象接口的“预处理”“善后处理”工作。代理类必须要是想CAbsSubjecrt接口,这样才能和被代理者保持相似。
(3)RealSubject: 具体的被代理的对象,具体的业务执行者。
2. 代理的优点
(1)职责清晰
被代理的对象,真实的subject就是实际的业务逻辑,只完成本职责的事物。
(2)高扩展性
具体的Subject随时都可能发生变化,只要接口不变,代理类能不变,及时Subject发生变换。
(3)智能化
通过“动态代理”,完成智能完成多点接入操作。
3. 代理的适用场景
在实际的编程中,代理的应用场景非常多,SpringAOP(面向切面编程)就是一个智能动态代理应用。
(1)当常见一个大的对象的时候,如创建一个大的图片,可以使用代理来完成创建的过程
(2)为网络上的一个对象创建一个局部的本地代理,我们将操作网络上对象的过程通过操作本地代理来完成。
(3)对对象进行不同的权限控制访问的时候,不同权限的用户提供不同的操作权限,把这一控制过程交给代理对象来完成。
(4)类似于智能指针的操作方法,也使用到了代理思想。
4. 代理的讨论与扩展
(1)代理的扩展
普通代理模式:
环境只能访问代Proxy角色,而不能访问真实的Subject。即环境不能new 具体的Subject对象,只能通过代理类操作相应的Subject。
即代理角色管理真实角色,通过代理角色直接操作真实对象。
(在实际项目中,一般是通过禁止new真实Subect来实现。)
强制代理模式:
强制环境必须通过真实角色来查找代理角色,然后才能访问真实角色的属性方法。即不支持直接new CrealSubject,以及不允许new CProxy
都不能访问。强制使用CRealSubject指定的CProx类才能访问。即真实角色管理代理类。在CabsSubject中添加getProxy()方法,返回指定的代理对象。
并在真实对象实现的方法中进行检测代理对象是否有效来判定限制。
有个性的代理类:
代理类Proxy不仅可以实现CAbsSubject接口,而且也可以实现其他不同的接口,通过对CRealSubject的借口进行“过滤”拦截,从而增强CRealSubject。
也可以组合其他真实的角色,这种情况下,代理类的职责并不一定单一。增强CrealSubject的预处理、过滤过滤消息、消息转发、事后处理消息。
动态代理模式:
定义,实现阶段并不关心代理的对象是谁,而是在运行阶段才指定哪一个对象。前面自己写代理类的属于“静态代理类”。
AOP(Aspect Oriented Programming)核心思想就是采用了动态代理机制。在Java语言环境下可以提供动态代理接口InvocationHandler。
AOP编程,对于我们的日志、事物、权限等都可以在系统设计阶段不用考虑,而在设计之后通过AOP贬称该技术方法,简单实现负责的作用。
动态代理是代理的职责,是一个通用类,不具有业务意义。具体的CRealsubject实现相关的逻辑功能,二者之间没有相互耦合的关系。
程序实现(C++)
Proxy.h
1 #pragma once 2 #include <iostream> 3 4 using namespace std; 5 6 /* 7 1.0 最简化的proxy类型结构 8 (1)CAbsSubject类抽象接口 9 (2)CRealSubject , CProxy都要实现CAbsSubject接口,这样二者维持相似 10 (3)CProxy 组合拥有一个CAbsSubject的引用或者指针,通过此指针完成对真实实现的预处理以及售后处理。 11 */ 12 class CAbsSubject 13 { 14 public: 15 virtual void methodInvoke() = 0; 16 }; 17 18 class CRealSubject :public CAbsSubject 19 { 20 public: 21 void methodInvoke() override 22 { 23 cout << "实际对象调用方法执行中..." << endl; 24 } 25 26 }; 27 28 class CProxy : public CAbsSubject 29 { 30 public: 31 CProxy(CAbsSubject* p) :m_pSubject(p){}; 32 //不释放被代理的对象 33 ~CProxy(){}; 34 void methodInvoke() override 35 { 36 cout << "对象预处理...." << endl; 37 m_pSubject->methodInvoke();//真实调用的实现部分 38 cout << "对象善后处理...." << endl; 39 } 40 41 private: 42 CAbsSubject* m_pSubject; 43 }; 44 45 /* 46 1.1A 代理扩展:普通代理模式框架A 47 环境只能访问代Proxy角色,而不能访问真实的Subject。即环境不能new 具体的Subject对象,只能通过代理类操作相应的Subject。 48 (在代理内部实现真实Subject的创建,然后在真实Subject的沟站函数传入表示病判断) 49 //或者直接将CRealSubject类构造声明为Protect:即可,但是太绝对 50 */ 51 52 class CAbsSubjectA 53 { 54 public: 55 virtual void methodInvoke() = 0; 56 57 }; 58 59 class CRealSubjectA : public CAbsSubjectA 60 { 61 public: 62 CRealSubjectA(CAbsSubjectA* p = nullptr) 63 { 64 if (!p) 65 throw "不能直接创建具体Subject使用,请借助于派生类..."; 66 67 } 68 void methodInvoke() override 69 { 70 cout << "实际对象调用方法执行中..." << endl; 71 } 72 73 }; 74 75 class CProxyA : public CAbsSubjectA 76 { 77 public: 78 CProxyA() 79 { 80 m_pSubject = new CRealSubjectA(this); 81 } 82 ~CProxyA() 83 { 84 delete m_pSubject; 85 } 86 //如果不继承基累的virtual纯虚拟方法,则不能创建对象this; 87 void methodInvoke() override 88 { 89 cout << "对象预处理...." << endl; 90 m_pSubject->methodInvoke();//真实调用的实现部分 91 cout << "对象善后处理...." << endl; 92 } 93 94 private: 95 CAbsSubjectA* m_pSubject; 96 }; 97 98 /* 99 1.1B 代理扩展:强制代理模式框架A 100 强制环境必须通过真实角色来查找代理角色,然后才能访问真实角色的属性方法。即不支持直接new CrealSubject,以及不允许new CProxy 101 都不能访问。强制使用CRealSubject指定的CProx类才能访问。即真实角色管理代理类。在CabsSubject中添加getProxy()方法,返回指定的代理对象。 102 并在真实对象实现的方法中进行检测代理对象是否有效来判定限制。 103 只要CRealSubject的getprox()没有调用,则成员一致为空,则方法就不能调用,所以必须在CREalSubject中的方法中进行代理类判定。 104 */ 105 106 class CAbsSubjectB 107 { 108 public: 109 virtual void methodInvoke() = 0; 110 virtual CAbsSubjectB* getTheProxy() = 0; 111 }; 112 113 class CProxyB : public CAbsSubjectB 114 { 115 public: 116 //代理特定的对象 117 CProxyB(CAbsSubjectB* p) 118 { 119 m_pSubject = p; 120 } 121 //只使用,不清楚管理的指针 122 ~CProxyB() 123 { 124 } 125 //如果不继承基累的virtual纯虚拟方法,则不能创建对象this; 126 void methodInvoke() override 127 { 128 cout << "对象预处理...." << endl; 129 m_pSubject->methodInvoke();//真实调用的实现部分 130 cout << "对象善后处理...." << endl; 131 } 132 //必须实现--没有意义 133 CAbsSubjectB* getTheProxy() 134 { 135 return this; 136 } 137 private: 138 CAbsSubjectB* m_pSubject; 139 }; 140 141 //智能使用真实对象指定的带来执行 142 class CRealSubjectB : public CAbsSubjectB 143 { 144 public: 145 CRealSubjectB() 146 { 147 m_pProxy = nullptr; 148 } 149 void methodInvoke() override 150 { 151 if (isValidateProx()) 152 { 153 //管理指定的具体对象的代理 154 cout << "实际对象调用方法执行中..." << endl; 155 } 156 else 157 { 158 throw "强制使用(1)CrelSubject指定的(2)Cproxy对象调用...两个条件限制"; 159 } 160 } 161 //此方法不调用,m_pProxy永远为nullptr,则其方法永远不能调用 162 CAbsSubjectB* getTheProxy() 163 { 164 m_pProxy = new CProxyB(this); 165 return m_pProxy; 166 } 167 168 private: 169 bool isValidateProx() 170 { 171 if (m_pProxy) 172 return true; 173 else 174 return false; 175 } 176 private: 177 CAbsSubjectB* m_pProxy; 178 }; 179 180 /* 181 1.1B 代理扩展:C++实现动态代理机制实现??? 182 */
(1)模板应用
main.cpp
1 // Proxys.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 7 #include "ProxyDef.h" 8 using namespace std; 9 10 11 int _tmain(int argc, _TCHAR* argv[]) 12 { 13 14 cout << "--------------------简单框架" << endl; 15 CAbsSubject* p = new CRealSubject(); 16 CProxy* pProxy = new CProxy(p); 17 pProxy->methodInvoke(); 18 19 20 cout << "--------------------普通代理类型框架:只允许使用代理类" << endl; 21 try 22 { 23 CAbsSubjectA* pA = new CRealSubjectA(); 24 25 } 26 catch (const char* error_c) 27 { 28 cout << "Error catched! ; " << error_c << endl; 29 30 } 31 32 CProxyA* pProxA = new CProxyA(); 33 pProxA->methodInvoke(); 34 35 36 cout << "--------------------强制代理框架:只允许使用CRealSubject" << endl; 37 try 38 { 39 CAbsSubjectB* pB = new CRealSubjectB(); 40 CProxyB* pProxyB = new CProxyB(pB); 41 //直接另外新建代理调用 42 pProxyB->methodInvoke(); 43 44 } 45 catch (const char* error_c) 46 { 47 cout << "Error catched! ; " << error_c << endl; 48 49 } 50 51 try 52 { 53 CAbsSubjectB* pB = new CRealSubjectB(); 54 //对象调用 55 pB->methodInvoke(); 56 57 } 58 catch (const char* error_c) 59 { 60 cout << "Error catched! ; " << error_c << endl; 61 62 } 63 //正常调用 64 CRealSubjectB* pRealB = new CRealSubjectB(); 65 CAbsSubjectB* pB = pRealB->getTheProxy(); 66 pB->methodInvoke(); 67 68 cout << "--------------------动态代理框架" << endl; 69 70 system("pause"); 71 return 0; 72 }
(2)输出展示