作用
代理模式主要用于,通过代理类,来控制实际对象的访问权限
案例
class VideoSite
{
public:
virtual void freeVideo()=0;
virtual void vipVideo()=0;
virtual void trickVideo()=0;
};
class FixBugVideoSite:public VideoSite
{
public:
void freeVideo(){cout<<"免费观看电影"<<endl;}
void vipVideo(){cout<<"vip客户观看电影"<<endl;}
void trickVideo(){cout<<"购买电影票观看电影"<<endl;}
};
void test()
{
unique_ptr<VideoSite> p1(new FixBugVideoSite());
//没有代理类的情况下,所有客户都可以观看所有电影
p1->freeVideo();
p1->vipVideo();
p1->trickVideo();
}
我们在这段代码里定义了三个功能,来模拟不同的客户观看电影的权限
- 普通用户:只能免费观看电影
- vip用户:可以观看vip电影和免费电影
- 购票用户:可以观看免费电影、vip电影和购票电影
显然对于不同种类的电影,有不同的观看权限。因此,我们要想办法给不同种类的电影赋予不同的权限,这就是代理模式的作用
我们直接看代码
//免费用户代理类
class FreeVideoProxy:public VideoSite
{
public:
FreeVideoProxy():_videoPtr(new FixBugVideoSite()){}
void freeVideo()
{
_videoPtr->freeVideo();
}
void vipVideo()
{
cout<<"您不是vip用户!"<<endl;
}
void trickVideo()
{
cout<<"请购买电影票观看!"<<endl;
}
private:
VideoSite* _videoPtr;
};
void watchVideo(unique_ptr<VideoSite>& videoPtr)
{
videoPtr->freeVideo();
videoPtr->vipVideo();
videoPtr->trickVideo();
}
void test()
{
unique_ptr<VideoSite>p1(new FreeVideoProxy());
watchVideo(p1);
}
上述代理类的设计控制了非vip用户和非购票用户观看电影的权限,在测试代码里,我们只需使用代理类即可完成对该用户观看电影的权限问题,而不必在原业务的代码上进行修改,大大降低了代码出错的风险。
同理,我们也可以给另外两种用户添加代理类以控制其观看电影的权限,如下:
vip用户代理类
class VipVideoProxy:public VideoSite
{
public:
VipVideoProxy():_videoPtr(new FixBugVideoSite()){}
void freeVideo()
{
_videoPtr->freeVideo();
}
void vipVideo()
{
_videoPtr->vipVideo();
}
void trickVideo()
{
cout<<"请购买电影票观看!"<<endl;
}
private:
VideoSite* _videoPtr;
};
购票用户代理类
class TrickVideoProxy:public VideoSite
{
public:
TrickVideoProxy():_videoPtr(new FixBugVideoSite()){}
void freeVideo()
{
_videoPtr->freeVideo();
}
void vipVideo()
{
_videoPtr->vipVideo();
}
void trickVideo()
{
_videoPtr->trickVideo();
}
private:
VideoSite* _videoPtr;
};
测试代码
void test()
{
unique_ptr<VideoSite>p1(new FreeVideoProxy());
unique_ptr<VideoSite>p2(new VipVideoProxy());
unique_ptr<VideoSite>p3(new TrickVideoProxy());
cout<<"普通用户:"<<endl;
watchVideo(p1);
cout<<"----------------------"<<endl;
cout<<"vip用户:"<<endl;
watchVideo(p2);
cout<<"----------------------"<<endl;
cout<<"购票用户:"<<endl;
watchVideo(p3);
cout<<"----------------------"<<endl;
}
在测试代码里可以看到,基于这种设计下,FixBugVideoSite类可不必关心业务权限的问题,只需开发不同种类的电影观看业务即可,而电影的观看权限则控制则由代理类完成,使用不同的代理类即可控制不同用户不同电影的观看权限