系列文章目录
C++技能系列
Linux通信架构系列
C++高性能优化编程系列
深入理解软件架构设计系列
高级C++并发线程编程
设计模式系列
期待你的关注哦!!!
现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。
Now everything is for the future of dream weaving wings, let the dream fly in reality.
结构型设计模式之代理模式
- 系列文章目录
- 一、代理模式介绍
- 二、代理模式优缺点
- 2.1 优点
- 2.2 缺点
- 三、代理模式使用场景
- 四、代理模式实现
一、代理模式介绍
⚠️ 意图:
在不改变原始类(或称为被代理类)的情况下,通过引入代理类来给原始类附加不相关的其他功能。为其他对象提供一种代理控制对这个对象的访问。
⚠️ 主要解决:
在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
⚠️ 何时使用:
想在访问一个类时做一些控制。
⚠️ 如何解决:
增加中间层。
代理模式本质是在访问对象的时候引入了一定程度的间接性,由于间接性访问对象,可以附加多种用途。
二、代理模式优缺点
2.1 优点
-
代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
-
职责清晰。实现好内部结构就可以,具体客户要求由代理进行分化。
-
高扩展性。具体主题角色随时变化,只要实现了接口,无论如何都逃不出代理的手掌,所以代理无论如何都是可以使用的。
-
远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
-
虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
-
保护代理可以控制对真实对象的使用权限。
2.2 缺点
-
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
-
实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
三、代理模式使用场景
-
远程代理:为一个对象在不同的地址空间提供局部代表,可以隐藏一个对象存在于不同地址空间的事实。
-
虚拟代理:根据需要创建开销很大的对象。通过虚拟代理来存放实例化需要很长时间的真实对象。例如:图片加载的时候。
-
安全代理:用来控制真是对象访问时的权限。
-
智能指引:当调用真实的对象的时候,代理处理另外一些事。
如果用户不能直接访问真实角色,只能访问代理,则需要让代理自动生成一个真实角色对象。
适配器模式中适配器为所适配的对象提供了一个不同的接口,代理模式中代理提供的接口与实体的接口相同。装饰模式的目的是为对象添加功能,而代理模式则控制对对象的访问。
四、代理模式实现
Subject抽象类:
#ifndef SUBJECT_H
#define SUBJECT_H
#include <iostream>
using namespace std;
//定义了Proxy和ConcreteSubject的公有接口
class Subject
{
public:
virtual ~Subject(){}
virtual void request() = 0;
protected:
Subject(){}
};
#endif // SUBJECT_H
ConcreteSubject真实主题类:
#ifndef CONCRETESUBJECT_H
#define CONCRETESUBJECT_H
#include "Subject.h"
//定义真实主题类
class ConcreteSubject : public Subject
{
public:
ConcreteSubject(){}
~ConcreteSubject(){}
void request()
{
cout << "ConcreteSubject::request" << endl;
}
};
#endif // CONCRETESUBJECT_H
Proxy代理类:
#ifndef PROXY_H
#define PROXY_H
#include "Subject.h"
#include "ConcreteSubject.h"
//定义代理类
class Proxy : public Subject
{
public:
Proxy():m_pSubject(NULL){}
~Proxy()
{
delete m_pSubject;
m_pSubject = NULL;
}
void request()
{
if(NULL == m_pSubject)
{
m_pSubject = new ConcreteSubject();
}
//额外操作
doSomethingA();
//代理实体的操作
m_pSubject->request();
//额外操作
doSomethingB();
}
void doSomethingA()
{
cout << "Proxy::doSomethingA" << endl;
}
void doSomethingB()
{
cout << "Proxy::doSomethingB" << endl;
}
private:
Subject* m_pSubject;
};
#endif // PROXY_H
客户调用程序:
#include "Proxy.h"
int main()
{
//使用代理取代ConcreteSubject
Proxy* proxy = new Proxy();
proxy->request();
delete proxy;
return 0;
}