Linux C++ 052-设计模式之享元模式
本节关键字:Linux、C++、设计模式、享元模式
相关库函数:
概念
享元模式(FlyWeight),运用共享技术有效的支持大量细粒度的对象。
典型的享元模式的例子为文书处理器中以图形结构来表示字符。一个做法是,每个字形有其字型外观, 字模 metrics,和其它格式资讯,但这会使每个字符就耗用上千字节。取而代之的是,每个字符参照到一个共享字形物件,此物件会被其它有共同特质的字符所分享;只有每个字符(文件中或页面中)的位置才需要另外储存。
使用场景
两个状态
内蕴状态存储在享元内部,不会随环境的改变而有所不同,是可以共享的。
外蕴状态是不可以共享的,它随环境的改变而改变的,因此外蕴状态是由客户端来保持(因为环境的变化是由客户端引起的)。
如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销的时候就可以考虑是否可以使用享元模式。
例如,如果发现某个对象的生成了大量细粒度的实例,并且这些实例除了几个参数外基本是相同的,如果把那些共享参数移到类外面,在方法调用时将他们传递进来,就可以通过共享大幅度单个实例的数目。
角色说明
1、抽象享元角色:为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。在Java中可以由抽象类、接口来担当。
2、具体享元角色:实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。
3、享元工厂角色:负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键!
4、客户端角色:维护对所有享元对象的引用,而且还需要存储对应的外蕴状态。
代码示例
cpp
// 运用共享技术(享)有效地支持大量细粒度(元)的对象。在有大量的对象时,把其中共有的部分抽象出来,如果有相同的业务请求时,直接返回内存中已有的对象,避免重新创建
// 享元模式的使用情况:
// 系统中有大量的对象,消耗大量的内存,且这些对象的状态可被外部化
// 对于享元模式,对象的信息分为两个部分:内部状态和外部状态
// 内部状态:指被共享出来的信息,存储在享元对象的内部,且不随环境改变
// 外部状态:不可共享,随环境改变而改变,有客户端来控制
//
// 享元类接口
class WebSite
{
public:
virtual void use() = 0;
};
// 具体的享元类
class ConcreteWebSite : public WebSite
{
private:
string name;
public:
ConcreteWebSite(string name) {
this->name = name;
}
void use() {
cout << "website catagory: " << endl;
}
};
// 享元工厂
class WebSiteFactory
{
private:
map<string, WebSite*> wf;
public:
WebSite* getWebSiteCategory(string key) {
if (wf.find(key) == wf.end()) {
wf[key] = new ConcreteWebSite(key);
}
return wf[key];
}
int getWebSiteCount() {
return wf.size();
}
};
int main_WebSite()
{
WebSiteFactory* wf = new WebSiteFactory();
WebSite* fx = wf->getWebSiteCategory("good");
fx->use();
WebSite* fy = wf->getWebSiteCategory("present");
fy->use();
WebSite* fz = wf->getWebSiteCategory("present");
fz->use();
cout << wf->getWebSiteCount() << endl;
return 0;
}
/* 运行结果: 上述代码中,我们发现相同的对象将不再创建,直接使用之前已有的
website catagory: good
website catagory: present
website catagory: present
website catagory: blog
website catagory: blog
3
*/