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

 

时间: 2024-10-17 14:36:15

23 DesignPatterns学习笔记:C++语言实现 --- 2.7 Proxy的相关文章

23 DesignPatterns学习笔记:C++语言实现 --- 1.5 Prototype

2016-07-21 (www.cnblogs.com/icmzn) 模式理解 1. Prototype  原型模式定义    提供了类的自我复制的能力,即通过已有对象进行新对象的创建.因为原型模式实在内存中进行二进制流的拷贝,所以比直接通过new 一个对象性能好.不同的实现方式与具体的语言相关. 2. 原型模式的优点(1)性能优良,实在内存中基于二进制的拷贝(2)在进行原型模式的时候,并不通过构造函数. 3. 原型模式的适用场景(1)需要根据已有对象创建大量的对象:(2)某个对象的创建需要有大

23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite

2016-07-22 (www.cnblogs.com/icmzn) 模式理解   1. Composite组合模式    又称为部分整体模式,主要用来描述部分与整体的关系.    将对象组合成树状结构以表示“部分-整体”的层次结构,是用户对“单个对象”和“组合对象”的使用具有一致性.    一般该模式具有三个角色:    (1)AbsComponent角色:一般为抽象父类,抽象“单个对象”“组合对象”公共的行为和方法,可以提供一些默认的方法或行为实现.    (2)Leaf角色:描述的是“单个

23 DesignPatterns学习笔记:C++语言实现 --- 2.6 Facade

2016-07-22 (www.cnblogs.com/icmzn) 模式理解   1. 门面模式 facade ,又称为外观模式    要求所有外部与一个子系统的所有通信必须通过一个“统一的对象”进行.这个对象就是子系统的“门面”,即门面提供一个统一的调用接口,使得    子系统能够简单使用.    门面模式注重“统一的对象”,除了这个统一的对象外,不允许以其他方式调用子系统的行为发生.子系统可以是一个类对象或者一组对象的集合,更直观的    讲不管子系统内是多么杂乱无章,只要“统一对象”是简

23 DesignPatterns学习笔记:C++语言实现 --- 2.2 Adapter

2016-07-22 (www.cnblogs.com/icmzn) 模式理解 1. Adapter 定义    将一个类的接口变换为客户端所期待的另一种接口形式,使被适配者Adaptee能用用在目标target的环境中    一般可以分为以下角色:    (1)Target角色:        定义把其他类或者对象转化为的目标接口.通常为一个抽象类(接口).    (2)Adaptee角色:        定义被转化的类,它是已经存在的类或者对象    (3)Adapte角色:        

23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge

2016-07-22 (www.cnblogs.com/icmzn) 模式理解   1. Bridge模式的定义    将抽象与实现解耦,使两个可以独立的发生变化.桥接模式的重点在“解耦”.    一般桥接模式有以下四个角色    (1)“抽象角色的抽象”:通过组合保留“实现橘色”的引用.    (2)具体的“抽象角色”:通过组合引用的实现类,对实现类抽象进行操作处理.    (3)“实现角色的抽象”:抽象类,定义实现角色必须的动作和行为.    (4)具体的实现角色:完成实现类角色抽象的具体的

23 DesignPatterns学习笔记:C++语言实现 --- 2.5 Factory

2016-07-18 (www.cnblogs.com/icmzn) 模式理解   1. Flyweight 模式,即享元(共享单元)模式    Flyweeight是拳击比赛中的特有名词,称为“特轻量级别”,则在设计模式中指的的是类要轻量.类的粒度要细,可以实现细粒度类的复用,但没有缺乏共享的机制,即多线程下类不可复用.    享元模式,是“池技术”的重要实现方式,但二者并不等价.使用享元模式可以支持大量的细粒度的对象的共享.    因为创建太多的对象到程序中有损程序的性能,可以采用享元模式的

IOS学习笔记---C语言第四天

1 //?生成2个数组,每个数组都有10个元素,元素取值范围20-40之间,数组对应元素相 加,放到另外?一个数组中 2 #import <Foundation/Foundation.h> 3 4 int main(int argc, const char * argv[]) 5 { 6 7 int num1[10]={0},num2[10]={0},num3[10]={0}; 8 for (int i = 0; i<10; i++) { 9 num1[i]=arc4random()%2

iOS学习笔记---c语言第十一天

函数指针 一.函数指针定义 //函数声明:声明我是一个什么函数 //求两个数的和 //函数的类型:int (int x,int y) //即:我是一个返回值为整型,有两个整型参数的函数. //函数名是 sum int sum(int x,int y); 函数指针定义p是变量,其他是类型(通常没有形参a,b) //函数指针类型 int (*)(int x,int y) //描述:指向 返回值为 int 两个int参数 的 指针类型 //函数指针变量: p //初始值 : sum printf("%

iOS学习笔记---c语言第九天

高级指针 指向结构体变量的指针,称为结构体指针 可以使用->指向内容. %p打印地址 void pLenth(cPoint *p1,cPoint *p2) //求两点间的距离  用的开方函数sqrt()和平方函数pow(,) { float a = sqrt(pow((p1->x-p2->x), 2)+pow((p1->y-p2->y), 2)); printf("两点距离为%.2f\n",a); } //main.m中代码 #import <Fou