目录
设计模式概念
简单来说,设计模式就是在解决某一类问题时,有既定的优秀的代码框架可以用,优点如下:
- 代码易于维护;
- 能够做到软件设计的开-闭原则(对修改关闭,对扩展开放);
- 合理的设计模式,能够做到软件设计的高内聚,低耦合。
代理模式的作用
代理模式也称为委托模式,作用就是找一个对象来替我们访问某个对象;
意图:为其它对象提供一种代理以控制对这个对象的访问,访问权限不同,内容也就不同。
下面我们模拟某个视频软件的功能来实现代理模式:
首先,针对这个视频软件:
- 如果你是普通用户的话,你只能观看免费电影;
- 如果你是VIP用户的话,你可以观看免费电影和VIP电影;
- 如果你是VIP用户,而且你还持有电影券,那么你可以观看所有电影。
针对以上的需求,代理模式就需要根据用户所处的身份,给用户呈现不同的内容,当发生“越权”访问的时候,给予提示 “ 等级不够,请充值 ” ,哈哈哈.......
下面直接看代码:
1、代理类中定义一个委托类对象指针(往下看)
#include<iostream>
#include<memory>
using namespace std;
// 代理类中定义一个委托类对象指针
class VideoSite // #1 抽象类
{
public:
virtual void freeMovie() = 0; // 免费电影
virtual void vipMovie() = 0; // vip电影
virtual void ticketMovie() = 0; // 用券观看电影
};
class FixBugVideoSite : public VideoSite // #2 委托类
{
public:
virtual void freeMovie()
{
cout << "观看免费电影" << endl;
}
virtual void vipMovie()
{
cout << "观看vip电影" << endl;
}
virtual void ticketMovie()
{
cout << "用券观看电影" << endl;
}
};
class FreeVideoSiteProxy : public VideoSite // #3 代理类
{
public:
FreeVideoSiteProxy() {Video = new FixBugVideoSite();}
~FreeVideoSiteProxy() {delete Video;}
virtual void freeMovie()
{
Video->freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie()
{
cout << "您目前只是普通游客,需要升级成VIP,才能观看VIP电影" << endl;
}
virtual void ticketMovie()
{
cout << "您目前没有券,需要购买电影券,才能观看电影" << endl;
}
private:
FixBugVideoSite* Video; // #4 代理类提供一个委托类对象
};
class VipVideoSiteProxy : public VideoSite // #3 代理类
{
public:
VipVideoSiteProxy() {Video = new FixBugVideoSite();}
~VipVideoSiteProxy() {delete Video;}
virtual void freeMovie()
{
Video->freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie()
{
Video->vipMovie();
}
virtual void ticketMovie()
{
cout << "您目前没有券,需要购买电影券,才能观看电影" << endl;
}
private:
FixBugVideoSite* Video; // #4 代理类提供一个委托类对象
};
// 这些是通用的API接口,使用的都是基类的指针或者引用
void watchMovie(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);
watchMovie(p1);
watchMovie(p2);
return 0;
}
针对以上代码,分析如下:
- 首先定义一个抽象类,提供对外的接口(纯虚函数),包括三种权限的电影;
- 其次定义一个委托类,继承于抽象类,重写接口,具体展示三类电影;
- 然后针对不同权限的电影,定义不同的代理类,也继承于抽象类,注意在每个代理类中包含一个委托类的对象或者对象指针;
- 最后我们就可以在主程序中使用了,定义一个抽象类指针指向代理类,代理类内部通过委托类对象或者对象指针访问委托类。
结果如下:
2、代理类中定义一个委托类对象
#include<iostream>
#include<memory>
using namespace std;
// 代理类中定义一个委托类对象
class VideoSite // #1 抽象类
{
public:
virtual void freeMovie() = 0; // 免费电影
virtual void vipMovie() = 0; // vip电影
virtual void ticketMovie() = 0; // 用券观看电影
};
class FixBugVideoSite : public VideoSite // #2 委托类
{
public:
virtual void freeMovie()
{
cout << "观看免费电影" << endl;
}
virtual void vipMovie()
{
cout << "观看vip电影" << endl;
}
virtual void ticketMovie()
{
cout << "用券观看电影" << endl;
}
};
class FreeVideoSiteProxy : public VideoSite // #3 代理类
{
public:
// FreeVideoSiteProxy() {Video = new FixBugVideoSite();}
// ~FreeVideoSiteProxy() {delete Video;}
virtual void freeMovie()
{
Video.freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie()
{
cout << "您目前只是普通游客,需要升级成VIP,才能观看VIP电影" << endl;
}
virtual void ticketMovie()
{
cout << "您目前没有券,需要购买电影券,才能观看电影" << endl;
}
private:
FixBugVideoSite Video; // #4 代理类提供一个委托类对象
};
class VipVideoSiteProxy : public VideoSite // #3 代理类
{
public:
// VipVideoSiteProxy() {Video = new FixBugVideoSite();}
// ~VipVideoSiteProxy() {delete Video;}
virtual void freeMovie()
{
Video.freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie()
{
Video.vipMovie();
}
virtual void ticketMovie()
{
cout << "您目前没有券,需要购买电影券,才能观看电影" << endl;
}
private:
FixBugVideoSite Video; // #4 代理类提供一个委托类对象
};
class TicketVideoSiteProxy : public VideoSite
{
public:
virtual void freeMovie()
{
Video.freeMovie(); // 通过代理对象的freeMovie,来访问真正委托类对象的freeMovie方法
}
virtual void vipMovie()
{
Video.vipMovie();
}
virtual void ticketMovie()
{
Video.ticketMovie();
}
private:
FixBugVideoSite Video;
};
// 这些是通用的API接口,使用的都是基类的指针或者引用
void watchMovie(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);
unique_ptr<VideoSite> p3(new TicketVideoSiteProxy);
watchMovie(p1);
watchMovie(p2);
watchMovie(p3);
return 0;
}
结果如下:
总结:代理模式还是挺有意思的,hhhhhhh