1、意图
运用共享技术有效地支持大量细粒度的对象。
2、适用性
Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用它。当以下情况都成立时使用Flyweight模式:
1)一个应用程序使用了大量的对象。
2)完全由于使用大量的对象,造成很大的存储开销。
3)对象的大多数状态都可变为外部状态。
4)如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
5)应用程序不依赖于对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
3、C++实例
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <atlstr.h>
#include <iostream>
#include <map>
#include <vector>
#include <string>
using namespace std;
class User
{
public:
string m_Username;
public:
User(string Username)
{
this->m_Username=Username;
}
string GetName()
{
return m_Username;
}
};
class WebSite
{
public:
virtual void Use(User user){}
};
class ConcreteWebSite:public WebSite
{
public:
string m_WebSitename;
public:
ConcreteWebSite(string WebsiteName)
{
this->m_WebSitename=WebsiteName;
}
virtual void Use(User user)
{
cout<<"网站分类:"<<m_WebSitename<<"用户:"<<user.m_Username<<endl;
}
};
class WebSiteFactory
{
public:
<span style="white-space:pre"> </span>// 对象共享
map<string,ConcreteWebSite*> m_Website;
public:
WebSite* GetWebSiteCategory(string Key)
{
map<string,ConcreteWebSite*>::iterator it=m_Website.find(Key);
if ( m_Website.end() == it )
{
m_Website[Key]=new ConcreteWebSite(Key);
return m_Website[Key];
}
else
{
return (WebSite*)it->second;
}
}
void GetWebSiteCount()
{
int length=0;
for (map<string,ConcreteWebSite*>::iterator it=m_Website.begin();
it!=m_Website.end();it++)
{
length++;
}
cout<<"网站分类总数为: "<<length<<endl;
}
~WebSiteFactory()
{
for (map<string,ConcreteWebSite*>::iterator it=m_Website.begin();
it!=m_Website.end();it++)
{
delete (it->second);
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
WebSiteFactory* fp=new WebSiteFactory;
WebSite* fxp=fp->GetWebSiteCategory("产品展示 ");
fxp->Use( User("小菜"));
WebSite* fyp=fp->GetWebSiteCategory("产品展示 ");
fyp->Use( User("大鸟"));
WebSite* fzp=fp->GetWebSiteCategory("产品展示 ");
fzp->Use( User("哈哈"));
WebSite* f1p=fp->GetWebSiteCategory("博客 ");
f1p->Use( User("老顽童"));
WebSite* fmp=fp->GetWebSiteCategory("博客 ");
fmp->Use( User("桃谷六仙"));
WebSite* fnp=fp->GetWebSiteCategory("博客 ");
fnp->Use( User("南海鳄神"));
fp->GetWebSiteCount();
delete(fp);
return 0;
}