享元模式
什么是享元模式
享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。
为什么使用享元模式
通过复用相同的对象来减少对象的创建数量,创建更小的对象组,并通过共享实现重用。通过归类,将对象的属性分为内蕴状态和外蕴状态。
外蕴状态是对象的外部描述,是每个对象的可变部分,比如对工具的使用地点、使用时间、使用人、工作内容的描述,这些属性不属于对象本身,而是根据每回使用情况进行变化的,这就需要制作成接口进行外部调用,而外蕴状态的维护是由调用者维护的,对象内不进行维护。
享元模式实现步骤
1.提供一个抽象享元角色类:具体享元类的父类,规定一些需要实现的公共接口
2.提供一个或者多个具体享元角色:实现了抽象享元角色规定的方法
3.提供一个享元工厂角色类:负责创建和管理享元角色
//车库信息
#include <initializer_list>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
using namespace std;
class SharedState {
public:
SharedState(const string brand, const string model, const string color)
: brand(brand), model(model), color(color) {}
friend ostream& operator<<(ostream& out, const SharedState ss) {
out << "[" << ss.brand << "," << ss.model << "," << ss.color << "]";
return out;
}
const string& GetBrand() const { return brand; }
const string& GetModel() const { return model; }
const string& GetColor() const { return color; }
private:
string brand; //品牌
string model; //型号
string color; //颜色
};
class UniqueState {
public:
UniqueState(const string owner, const string plates)
: owner(owner), plates(plates) {}
friend ostream& operator<<(ostream& out, const UniqueState ss) {
return out << "[" << ss.owner << "," << ss.plates << "]";
}
const string& GetOwer() const { return owner; }
const string& GetPlates() const { return plates; }
private:
string owner; //车主
string plates; //车牌
};
class Flyweight {
private:
SharedState* shared_state;
public:
Flyweight(const SharedState* shared_state)
: shared_state(new SharedState(*shared_state)) {}
Flyweight(const Flyweight& other)
: shared_state(new SharedState(*other.shared_state)) {}
SharedState* Get_shared_state() const { return shared_state; }
void Operation(const UniqueState& unique_state) const {
cout << "shared:" << *shared_state << endl
<< "unique:" << unique_state << endl;
}
};
class FlayweightFactory {
private:
map<string, Flyweight> flyweight;
string GetKey(const SharedState& ss) const {
return ss.GetBrand() + "_" + ss.GetModel() + "_" + ss.GetColor();
}
public:
FlayweightFactory(initializer_list<SharedState> shared_state) {
for (const SharedState& ss : shared_state) {
this->flyweight.insert(
make_pair<string, Flyweight>(this->GetKey(ss), Flyweight(&ss)));
}
}
Flyweight GetFlweight(const SharedState& shared_state) {
string key = this->GetKey(shared_state);
if (this->flyweight.find(key) == this->flyweight.end()) {
cout << "车库未找到....." << endl;
this->flyweight.insert(make_pair(key, Flyweight(&shared_state)));
cout << "第一次入库成功" << endl;
} else {
cout << "车库找到!......" << endl;
}
return this->flyweight.at(key);
}
void ListFlyweights() const {
int count = this->flyweight.size();
cout << "车库总信息:" << endl;
for (auto pair : this->flyweight) {
cout << pair.first << "\n";
}
}
};
void AddCarToPoliceDataBase(FlayweightFactory& ff,
const string& plates,
const string& ower,
const string& brand,
const string& model,
const string& color) {
cout << "车型匹配结果:" << endl;
const Flyweight& flyweight = ff.GetFlweight({brand, model, color});
flyweight.Operation({ower, plates});
}
int main() {
FlayweightFactory* factory =
new FlayweightFactory({{"雪佛兰", "Camaro2020", "pink"},
{"奔驰", "C43", "black"},
{"奔驰", "C63", "red"},
{"宝马", "M6", "red"},
{"宝马", "X7", "white"}});
AddCarToPoliceDataBase(*factory, "DK88888", "麦克", "宝马", "M6", "red");
AddCarToPoliceDataBase(*factory, "DK66666", "肖邦", "宝马", "X7", "red");
factory->ListFlyweights();
delete factory;
return 0;
}
享元模式优缺点
优点
-
如果程序中有很多相似对象, 那么你将可以节省大量内存。
缺点
-
你可能需要牺牲执行速度来换取内存, 因为他人每次调用享元方法时都需要重新计算部分情景数据。
-
代码会变得更加复杂。