系列总链接:https://blog.csdn.net/qq_22122811/article/details/112360387
参考:
https://www.cnblogs.com/daniels/p/8242592.html
https://www.runoob.com/design-pattern/proxy-pattern.html
https://blog.csdn.net/a369189453/article/details/81275740
一:概述
代理模式(proxy pattern):为其他对象提供一种代理以控制这个对象的访问;
理解:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择自己喜欢的车,然后付钱就可以了。
引入装饰模式的原因 :
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
开闭原则,增加功能:代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后对返回结果的处理等。代理类本身并不真正实现服务,而是同过调用委托类的相关方法,来提供特定的服务。真正的业务功能还是由委托类来实现,但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。
二:结构与实现
结构图:
介绍:
三:应用
在《大话设计模式》-装饰模式,这一章中,作者用了戴励(代理)帮助卓贾易追到娇娇,如下图:
书中的例子不赘述,这里用了网上找的另外一个例子 =》 中介代替小明去完成租房的工作,代码如下:
/*********************************************
* 代理模式 2021-01-27
**********************************************/
#include <QCoreApplication>
#include <QDebug>
#include <QTextCodec>
// Subject,人和中介的接口类
class Person
{
public:
virtual void rentHouse() = 0;
};
// realSubject, 小明是真实买房的人,继承于人
class XiaoM : public Person
{
public:
void rentHouse(){
qDebug() << "我要租房";
};
};
// Proxy, 中介代理小明买房子,这里不能理解为继承,因为关系是like_a, 还不是is_a
class Intermediary : public XiaoM
{
public:
Intermediary(){
}
void rentHouse() override{
if(m_person == NULL){
m_person = new XiaoM(); // 创建被代理对象,即实际是被代理对象进行操作
}
m_person->rentHouse();
};
private: // 需要设置为私有的,因为这里是一级代理,也是最后一级代理,所以是private
XiaoM* m_person;
};
// 真实场景
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
Intermediary* interRy = new Intermediary();
// 代理类帮实际对象完成操作
interRy->rentHouse();
return a.exec();
}
四:优缺点及适用环境
4.1:优缺点
优点:
职责清晰:真实角色就是实现实际的业务逻辑,不关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简介清晰。
高扩展性:具体主题角色可变。
缺点:
这种模式引入了另一个抽象层,这有时可能是一个问题。如果真实主题被某些客户端直接访问,并且其中一些客户端可能访问代理类,这可能会导致不同的行为。
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
4.2:适用场景
使用场景:
想在访问一个类时做一些控制。
应用例子:
1、Windows 里面的快捷方式。
2、猪八戒去找高翠兰结果是孙悟空变的,可以这样理解:把高翠兰的外貌抽象出来,高翠兰本人和孙悟空都实现了这个接口,猪八戒访问高翠兰的时候看不出来这个是孙悟空,所以说孙悟空是高翠兰代理类。
3、买火车票不一定在火车站买,也可以去代售点。
4、一张支票或银行存单是账户中资金的代理。支票在市场交易中用来代替现金,并提供对签发人账号上资金的控制。
书中说到的如下:
4.3:注意事项
1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
五:小结
代理模式实际上就是为了代理其他对象控制对这个的访问,如现实生活中的中介代理我们去租房子,外卖小哥代理我们去取外卖等等,这个符合设计原则中的扩展开放,修改关闭的原则。