码迷,mamicode.com
首页 > 编程语言 > 详细

23 DesignPatterns学习笔记:C++语言实现 --- 2.7 Proxy

时间:2016-07-23 00:35:46      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:

23 DesignPatterns学习笔记:C++语言实现 --- 2.7 Proxy

 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)输出展示

技术分享 

 

23 DesignPatterns学习笔记:C++语言实现 --- 2.7 Proxy

标签:

原文地址:http://www.cnblogs.com/icmzn/p/5697483.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!