大话设计模式(15)——享元模式(Flyweight)

享元模式(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值