目录
模式思想
简介
代理模式: 通过代理类,来控制实际对象的访问权限。
在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式 属于 结构型模式。
组成
- 抽象角色:通过接口或抽象类声明真实角色实现的业务方法;
- 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用;
- 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。(访问权限)
优点
- 职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他非本职的事务,通过后期的代理来完成事务,附带的结果就是编程简洁清晰;
- 代理对象可以在客户端和目标对象之间起到中介的作用,保护了目标对象;
- 高扩展性。
代码实现
情景
了解了代理模式的定义和优点以后,我们来模拟这样一个场景:
我们上视频网站上去看电影,电影也分有好几个级别: 免费电影、VIP电影、用券电影,不同的人可以看不同级别的电影
如果不使用代理的话:
我们可以看到还是纯在有很多的不足的,没用访问权限的控制。
加代理的话:
通过代理类,来控制用户的访问权限。
//抽象类
class VideoSite
{
public:
virtual void freeMovie() = 0; //免费电影
virtual void vipMovie() = 0; //vip电影
virtual void ticketMovie() = 0;//用券电影
};
//委托类
class FixBugVideoSite : public VideoSite
{
public:
virtual void freeMovie() //免费电影
{
cout << "观看免费电影" << endl;
}
virtual void vipMovie() //vip电影
{
cout << "观看vip电影" << endl;
}
virtual void ticketMovie() //用券电影
{
cout << "用券观看电影" << endl;
}
};
//普通用户代理类
class FreeVideSiteProxy : public VideoSite
{
public:
FreeVideSiteProxy()
{
pVideo = new FixBugVideoSite();
}
~FreeVideSiteProxy()
{
delete pVideo;
}
virtual void freeMovie() //免费电影
{
pVideo->freeMovie(); //通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie() //vip电影
{
cout << "不好意思,您不是VIP,请先充值。"<<endl;
}
virtual void ticketMovie()//用券电影
{
cout << "不好意思,您没有券,请先购买。"<<endl;
}
private:
FixBugVideoSite* pVideo;
};
//VIP用户代理类
class vipVideSiteProxy : public VideoSite
{
public:
vipVideSiteProxy()
{
pVideo = new FixBugVideoSite();
}
~vipVideSiteProxy()
{
delete pVideo;
}
virtual void freeMovie() //免费电影
{
pVideo->freeMovie(); //通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie() //vip电影
{
pVideo->vipMovie();
}
virtual void ticketMovie()//用券电影
{
cout << "不好意思,您没有券,请先购买。"<<endl;
}
private:
VideoSite* pVideo;
};
可以看到,我们代码里面的委托类FixBugVideoSite
就是上面提到的真实角色。它拥有了该网站所有视频的观看权限。
每一个代理类都有一个委托类
的数据成员。代理类通过委托类
来访问视频网站。并且,可以根据当前代理的用户的身份(普通游客
、VIP会员
),来限制其访问的内容。
为了模拟在视频网站上浏览视频的全部情景,我们可以设计一个函数,专门用来观看电影(免费电影
、VIP电影
、用券观看的电影)
void watchMovie(unique_ptr<VideoSite>& ptr)
{
ptr->freeMovie();
ptr->vipMovie();
ptr->ticketMovie();
}
结果
运行下面的代码:
void main()
{
unique_ptr<VideoSite> p1 (new FreeVideSiteProxy());
unique_ptr<VideoSite> p2(new vipVideSiteProxy());
watchMovie(p1);
cout << "--------------------------" << endl;
watchMovie(p2);
}