前言
代理模式属于设计模式中的构造型设计模式之一,又叫结构型设计模式,它可以为其它的对象提供一层代理机制,就是要访问其它对象不是直接去访问的,而是统一由代理类负则。你们肯定也听过代理服务器的嘛,比如翻墙,就是提供一层中间机制。
模式的结构
这张图就能很形象的说明结构了:
subject(抽象主题角色):真实主题与代理主题的共同接口。
RealSubject(真实主题角色):定义了代理角色所代表的真实对象。
Proxy(代理主题角色):含有对真实主题角色的引用,代理角色通常在
将客户端调用传递给真是主题对象之前或者之后执行某些操作,而不是单纯返
回真实的对象。
我知道这么说很难懂的,看着简单,下面看例子:
对照上面的结构来看,这里是最简单的类图了,上代码:
#include<iostream>
#include<string>
using namespace std;
//产品类
class Item
{
public:
Item(string name,bool istrue)
{
this->name = name;
this->istrue = istrue;
}
public:
string name;
bool istrue;
};
//抽象的购物类供代理类和实际的购物类依赖
class AbstractShop
{
public:
virtual void buy(Item& item) = 0;
};
//实际购物类继承抽象类
class AmericShop:public AbstractShop
{
public:
virtual void buy(Item& item)
{
cout << "美国购物买:" << item.name << endl;
}
};
class KoreaShop :public AbstractShop
{
public:
virtual void buy(Item& item)
{
cout << "韩国购物买:" << item.name << endl;
}
};
class EuropeShop :public AbstractShop
{
public:
virtual void buy(Item& item)
{
cout << "欧洲购物买:" << item.name << endl;
}
};
//代理类继承抽象类,负则管理购物类的方法,也是客户端应该去访问的购物类
class ProxyShop :public AbstractShop
{
public:
ProxyShop(AbstractShop* ss)
{
shop = ss;
}
//~ProxyShop()
//{
// cout << "111" << endl;
// //不用再delete,用智能指针管理的内存会自动释放,这样会造成重复释放,这里析构函数也可以不写了
// //delete shop;
// cout << "析构函数" << endl;
//}
virtual void buy(Item& item)
{
if (distinguish(item))
{
shop->buy(item);
}
else
{
cout << item.name << "是假的!" << endl;
}
}
private:
AbstractShop* shop;
bool distinguish(Item& item)
{
return item.istrue;
}
};
int main()
{
Item item1("adidas", true);
Item item2("nike", true);
Item item3("champion", false);
unique_ptr<AbstractShop> as(new AmericShop);
unique_ptr<AbstractShop> ks(new KoreaShop);
unique_ptr<AbstractShop> es(new EuropeShop);
ProxyShop proxyshop1(as.get());
ProxyShop proxyshop2(ks.get());
ProxyShop proxyshop3(es.get());
proxyshop1.buy(item1);
proxyshop2.buy(item2);
proxyshop3.buy(item3);
}
**我在代码中还使用了智能指针,记住,你要是在类中用到了指针,那么你就要记得在类的析构函数中释放这个指针的内存,避免内存泄漏,使用智能指针管理这块内存,就不用再次释放。**有点跑题,我之前也介绍过智能指针,真的很好用!
优缺点:
优点:
- 能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
- 客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源 代码,符合开闭原则,系统具有较好的灵活性和可扩展性。
缺点:
- 代理实现较为复杂。
写在最后
关于代理模式,我的理解是,当你想要给一些类加上使用条件,你就可以使用代理模式,简而言之就是:为其他对象提供一种代理以控制对这个对象的访问。
愿每一个程序员都能被温柔相待!