目录
定义
代理模式,也称为委托模式。定义为:
- 为其他对象提供一种代理以间接控制对这个对象的访问
代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。
其实代理模式无论是在日常开发还是设计模式中,基本随处可见。中介者模式中的中介者对象也是代理模式的应用,其他的对象的交互都是交给了中介者对象处理的。而在生活中就更多类似代理模式的例子,例如:抢票插件、代购、代理上网、打官司等。
代理模式分类
- 静态代理(静态定义代理类,我们自己静态定义的代理类。比如我们自己定义一个代购类)
- 动态代理(通过程序动态生成代理类,该代理类不是我们自己定义的。而是由程序自动生成的)
静态代理和动态代理是根据代码方面来区分的代理模式的。
- Subject:抽象主题类(也可以是接口),声明真实主题与代理的共同接口方法。
- RealSubject:实际主题类,也就是被代理的类,负责执行具体的业务逻辑方法;客户类调用代理类简介调用其定义的方法
- ProxySubject:代理主题类,也就是代理类,持有一个被代理类的引用,在实现抽象主题类的共同方法中调用被代理类相应的方法,起到代理的作用。
- Client:客户类,使用代理对象的类
静态代理一般具有如下特点:
- 代理类一般要持有一个被代理的对象的引用
- 对于我们不关心的方法,全部委托给被代理
- 自己处理我们关心的方法
代理模式的优点
- 代理模式可以屏蔽用户真正请求的对象,使用户程序和真正的对象之间解耦。
- 使用代理来担当那些创建耗时的对象的替身。
应用场景
- 远程代理,也就是为某个对象在不同的地址空间提供局部代表。使系统可以将
Server
部分的实现细节隐藏,以便Client
不必考虑Server
的存在- 虚拟代理,使用一个代理对象表示一个十分耗资源的对象并在真正需要时才创建。例如:图片加载的时候。
- 安全代理,用来控制真实对象访问时的权限。该类型的代理常被用于真实对象有不同访问权限的情况。
- 智能指引,是指当调用真实的对象的时候,代理处理另外一些事。
- 程序可能不希望用户直接访问该对象,而是提供一个代理对象以控制对当前对象的间接访问。
根本原理:代理模式其实就是在访问对象的时候引入了一定程度的间接性,因为这种间接性,可以附加多种用途
注意的是:静态和动态代理都可以应用于上述种情形,两者是各自独立的变化。
用C++代码实现大话设计模式本章代码:
#include<iostream>
#include<string>
using namespace std;
//SchoolGirl类
class SchoolGirl final // 添加 final 关键字 表明该类不能做一个基类
{
private:
std::string m_name;
public:
void setName(std::string name)
{
m_name = name;
}
string getName() { return m_name; }
};
// 抽象主题类(Subject)类,定义了 实际主题类(RealSubject)和代理类(Proxy)的共用接口,这样就可以在任何使用 RealSubject 的地方使用Proxy
class IGiveGift
{
public:
virtual ~IGiveGift() = default;
virtual void GiveDolls() = 0;
virtual void GiveFlowers() = 0;
virtual void GiveChocolate() = 0;
};
//实际主题(RealSubject)类,定义了代理类(Proxy)真正需要调用的方法
class Pursuit final : public IGiveGift
{
public:
explicit Pursuit(SchoolGirl *mm);
void GiveDolls() override;
void GiveFlowers()override;
void GiveChocolate() override;
private:
SchoolGirl *m_girl;
};
Pursuit::Pursuit(SchoolGirl *mm)
{
m_girl = mm;
}
void Pursuit::GiveDolls()
{
m_girl->setName("洋娃娃");
std::cout << "送给 m_girl:" << m_girl->getName() << endl;
}
void Pursuit::GiveFlowers()
{
m_girl->setName("鲜花");
std::cout << "送给 m_girl:" << m_girl->getName() << endl;
}
void Pursuit::GiveChocolate()
{
m_girl->setName("巧克力");
std::cout << "送给 m_girl:" << m_girl->getName() << endl;
}
//代理类(Proxy),保存一个引用使的代理对可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来替代实体
class Proxy final :public IGiveGift
{
private:
Pursuit *purObject;
public:
explicit Proxy(SchoolGirl *pur);
void GiveDolls() override;
void GiveFlowers()override;
void GiveChocolate() override;
};
Proxy::Proxy(SchoolGirl *pur)
{
purObject = new Pursuit(pur);
}
void Proxy::GiveDolls()
{
purObject->GiveDolls();
}
void Proxy::GiveFlowers()
{
purObject->GiveFlowers();
}
void Proxy::GiveChocolate()
{
purObject->GiveChocolate();
}
int main()
{
SchoolGirl *jiaojiao = new SchoolGirl;
jiaojiao->setName("李娇娇");
Proxy *daili = new Proxy(jiaojiao);
daili->GiveDolls();
daili->GiveFlowers();
daili->GiveChocolate();
delete jiaojiao;
jiaojiao = nullptr;
delete daili;
daili = nullptr;
system("pause");
return 0;
}
运行后的截图: