1、结构型模式(代理模式 & 适配器模式 & 装饰器模式)
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
2、代理模式
不是所有的客户都能访问到老板,老板的助理,即通过代理类,来控制实际对象的访问权限。
代理类和委托类是组合关系!!!
- 客户是不能直接使用委托类的,因为委托类是包含所有功能的!(有些访问时需要权限的)
- 代理类也是从基类派生的!客户是直接访问代理类的,代理类中有个抽象类的指针,指向为委托类的对象!(也就是在代理类中有一个委托类对象)
- 因为代理类和委托类都继承重写了基类的所有方法,因此代理类在成员方法中可以控制委托类的成员方法访问权限!
#include <iostream>
#include <memory>
using namespace std;
/*
代理Proxy模式 : 通过代理类,来控制实际对象的访问权限
客户 助理Proxy 老板 委托类
*/
class VideoSite // #1 抽象类
{
public:
virtual void freeMovie() = 0; // 免费电影
virtual void vipMovie() = 0; // vip电影
virtual void ticketMovie() = 0; // 用券观看电影
};
// 委托类 #2
class FixBugVideoSite : public VideoSite
{
public:
virtual void freeMovie() // 免费电影
{
cout << "观看免费电影" << endl;
}
virtual void vipMovie() // vip电影
{
cout << "观看VIP电影" << endl;
}
virtual void ticketMovie() // 用券观看电影
{
cout << "用券观看电影" << endl;
}
};
// 代理类 #3 代理FixBugVideoSite
class FreeVideoSiteProxy : public VideoSite
{
public:
FreeVideoSiteProxy() { Video = new FixBugVideoSite(); }
~FreeVideoSiteProxy() { delete Video; }
virtual void freeMovie() // 免费电影
{
Video->freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie() // vip电影
{
cout << "您目前只是普通游客,需要升级成VIP,才能观看VIP电影" << endl;
}
virtual void ticketMovie() // 用券观看电影
{
cout << "您目前没有券,需要购买电影券,才能观看电影" << endl;
}
private:
VideoSite* Video; // # 4 组合的方式
};
// 代理类 代理FixBugVideoSite
class VipVideoSiteProxy : public VideoSite
{
public:
VipVideoSiteProxy() { pVideo = new FixBugVideoSite(); }
~VipVideoSiteProxy() { delete pVideo; }
virtual void freeMovie() // 免费电影
{
pVideo->freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie() // vip电影
{
pVideo->vipMovie();
}
virtual void ticketMovie() // 用券观看电影
{
cout << "您目前没有券,需要购买电影券,才能观看电影" << endl;
}
private:
VideoSite* pVideo; //组合的方式
};
// 这些都是通用的API接口,使用的都是基类的指针或者引用
void watchMovice(unique_ptr<VideoSite>& ptr)
{
ptr->freeMovie();
ptr->vipMovie();
ptr->ticketMovie();
}
int main()
{
unique_ptr<VideoSite> p1(new FreeVideoSiteProxy()); // #5 客户直接访问代理对象
unique_ptr<VideoSite> p2(new VipVideoSiteProxy());
watchMovice(p1);
cout << "=============================" << endl;
watchMovice(p2);
return 0;
}
为不同的身份都提供了不同的代理模式!