享元模式 (Flyweight)
运用共享技术有效地支持大量细粒度的对象。
使用
- 如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时就应该考虑使用享元模式;
- 对象的大多数状态可以是外部状态,如果删除对象的外部状态那么可以用相对较少的共享对象取代很多组对象,此时可以考虑使用享元模式。
如五子棋,按照位置分类会有很多棋子对象,如果不考虑位置这些棋子也就黑白两类。 - 使用享元模式需要维护一个记录了系统已有的所有享元的列表,而这本身需要耗费资源,另外享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。因此,应当在有足够多的对象实例可供共享时才值得使用享元模式。
结构图
example
开发不同种类的网站,给不同的拥护使用。
#include <iostream>
#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
/* 享元模式 (Flyweight)
1. 运用共享技术有效地支持大量细粒度的对象。
# example
开发不同种类的网站,给不同的拥护使用
*/
class User
{
string name;
public:
User(string n) : name(n){}
string getName() { return name; }
};
class Website
{
public:
virtual void use(User &u) = 0;
};
class ConcreteWebsite : public Website {
string type;
public:
ConcreteWebsite(string n) : type(n){}
// 根据不同的账号(外部状态)使用网站
virtual void use(User &u){
cout << u.getName() << "使用 " << type << endl;
}
};
// 根据网站的类别 创建不同的实例对象
class Factory {
unordered_map<string,Website*> webs;
public:
Website* getWebsite(string type) { // 内部状态分类
if (webs.count(type)) {
return dynamic_cast<Website*>(webs[type]);
} else {
webs[type] = new ConcreteWebsite(type);
}
return nullptr;
}
};
int main()
{
User u1("u1");
Website *w1 = new ConcreteWebsite("产品展示");
w1->use(u1);
User u2("u2");
Website *w2 = new ConcreteWebsite("博客");
User u3("u3");
w2->use(u2);
w2->use(u3);
return 0;
}