享元模式(Flyweight)
享元模式(Flyweight):运用共享技术有效地支持大量细粒度的对象
网站共享
#include <iostream>
using namespace std;
#include <string>
#include <map>
class User {
private:
string name;
public:
User(string name) {
this->name = name;
}
string GetName(){
return this->name;
}
};
class Website {
public:
virtual void Use(User user) {}
};
class ConcreteWebsite :public Website {
private:
string name;
public:
ConcreteWebsite(string name) {
this->name = name;
}
void Use(User user) {
cout << "网站分类:" << name << " 用户:" << user.GetName() << endl;
}
};
class WebsiteFactory {
public:
WebsiteFactory(){}
~WebsiteFactory() {
/*for (auto& m : (m_map)) {
delete m.second;
}*/
map<string, Website*>::iterator it;
for (it = m_map.begin(); it != m_map.end(); it++) {
delete it->second;
}
}
Website* GetWebsiteGategory(string key) {
for (const auto& m : (m_map)) {
if (m.first == key)
return m.second;
}
Website* website = new ConcreteWebsite(key);
m_map.insert(pair<string, Website*>(key, website));
return website;
}
int GetWebsiteCount() {
return m_map.size();
}
private:
map<string, Website*> m_map;
};
//客户端
void test01() {
WebsiteFactory* f = new WebsiteFactory();
Website* fx = f->GetWebsiteGategory("产品展示");
fx->Use(User("小菜"));
Website* fy = f->GetWebsiteGategory("产品展示");
fy->Use(User("大鸟"));
Website* fz = f->GetWebsiteGategory("产品展示");
fz->Use(User("娇娇"));
Website* fm = f->GetWebsiteGategory("博客");
fm->Use(User("桃谷六仙"));
Website* fn = f->GetWebsiteGategory("博客");
fn->Use(User("南海鳄神"));
cout << "得到网站分类总数:" << f->GetWebsiteCount() << endl;
}
int main() {
test01();
return 0;
}
游戏玩家
#include <iostream>
using namespace std;
#include <string>
#include <map>
#include <ctime>
#define GET_ARRAY_LEN(array, len) {len = (sizeof(array) / sizeof(array[0]));}
//Flyweight 玩家——有武器和使命
class Player {
protected:
string m_task; //内部状态
string m_weapon; //外部状态
public:
virtual ~Player(){}
//分配武器
virtual void assignWeapon(string weapon) = 0;
//使命
virtual void mission() = 0;
};
//ConcreteFlyweight
//恐怖分子
class Terrorist :public Player{
public:
Terrorist() {
m_task = "放置炸弹";
}
void assignWeapon(string weapon) {
m_weapon = weapon;
}
void mission() {
cout << "恐怖分子的武器是:" + m_weapon + "," + " 使命是:" + m_task << endl;
}
};
//反恐精英
class CounterTerrorist :public Player {
public:
CounterTerrorist() {
m_task = "拆除炸弹";
}
void assignWeapon(string weapon) {
m_weapon = weapon;
}
void mission() {
cout << "反恐精英的武器是:" + m_weapon + "," + " 使命是:" + m_task << endl;
}
};
//FlyweightFactory 用于获得玩家
// 用于获取玩家
class PlayerFactory
{
public:
// 如果 T/CT 对象存在,则直接从享元池获取;否则,创建一个新对象并添加到享元池中,然后返回。
static Player* getPlayer(string type)
{
Player* p = NULL;
if (m_map.find(type) != m_map.end()) {
p = m_map[type];
}
else {
// 创建 T/CT 对象
if (type == "T") {
cout << "恐怖分子被创建" << endl;
p = new Terrorist();
}
else if (type == "CT") {
cout << "反恐精英被创建" << endl;
p = new CounterTerrorist();
}
else {
cout << "无效代码" << endl;
}
// 一旦创建,将其插入到 map 中
m_map.insert(make_pair(type, p));
}
return p;
}
private:
// 存储 T/CT 对象(享元池)
static map<string, Player*> m_map;
};
//静态数据成员初始化 此处必须初始化否则报错
map<string, Player*> PlayerFactory::m_map = map<string, Player*>();
//玩家类型和武器
static string s_playerType[2] = { "T","CT" };
static string s_weapons[4] = { "AK-47", "Maverick", "Gut Knife", "Desert Eagle" };
//客户端
void test01() {
srand((unsigned)time(NULL));
int playerLen;
int weaponsLen;
GET_ARRAY_LEN(s_playerType, playerLen);
GET_ARRAY_LEN(s_weapons, weaponsLen);
//假设,游戏中有十位玩家
for (int i = 0; i < 10; i++) {
//获取随机玩家和武器
int typeIndex = rand() % playerLen;
int weaponsIndex = rand() % weaponsLen;
string type = s_playerType[typeIndex];
string weapons = s_weapons[weaponsIndex];
//获取玩家
Player* p = PlayerFactory::getPlayer(type);
//从武器库中随机分配武器
p->assignWeapon(weapons);
//派玩家去执行任务
p->mission();
}
}
int main() {
test01();
system("pause");
return 0;
}