设计模式C++享元
注:原视频:【设计模式(完整版)】2.6享元_哔哩哔哩_bilibili
这个设计模式比较少用,因为这个问题出现需要这个设计模式时一般都会从别的层面解决,比如数据库层面,
分类:(对象)结构型
问题:做一个车管所系统,将会产生大量的车辆实体,如果每一个实例的都保存自己的所有信息,将会需要大量内存,甚至导致程序崩溃.
解决方案:运用共享技术有效的支持大量细粒度的对象.
享元模式能有效减少在画布上渲染数百万个树状对象时所需的内存
优点:
如果程序中有很多相似对象,那么你将可以节省大量内存.
缺点:
可能需要牺牲执行速度来换取内存,因为他人每次调用享元方法时都需要重新计算部分情景数据.
代码:
#include <iostream>
#include<string>
#include<unordered_map>
using std::string;
//内部状态
struct SharedState
{
string m_brand;
string m_model;
string m_color;
SharedState(const string& brand, const string model, const string color) :
m_brand(brand), m_model(model), m_color(color)
{
}
friend std::ostream& operator<<(std::ostream& os, const SharedState& ss)
{
return os << "[" << ss.m_brand << "," << ss.m_model << "," << ss.m_color << "]";
}
};
//外部状态
struct UniqueState
{
string m_owner;
string m_plates;
struct UniqueState(const string& owner, const string& plates) :
m_owner(owner), m_plates(plates)
{
}
friend std::ostream& operator<<(std::ostream& os, const UniqueState& ss)
{
return os << "[" << ss.m_owner << "," << ss.m_plates <<"]";
}
};
//享元,存放共享状态
class Flyweight
{
private:
SharedState m_sharedState;
public:
Flyweight(const SharedState sharedState) :m_sharedState(sharedState) {}
void operation(UniqueState uniqueState) const //使用的时候,使用外部状态作为参数,对整个context做出操作
{
std::cout << "Flyweight:显示内部状态("
<< m_sharedState << "),显示外部状态("
<< uniqueState << ")" << std::endl;
}
};
class FlyweightFactory
{
private:
std::unordered_map<string, Flyweight> m_Flyweights;
string getKey(const SharedState& ss) const
{
return ss.m_brand + "_" + ss.m_model + "_" + ss.m_color;
}
public:
FlyweightFactory(std::initializer_list<SharedState> share_states)
{
for (const SharedState& ss : share_states)
{
m_Flyweights.insert({ getKey(ss),Flyweight(ss) });
}
}
Flyweight* getFlyWeight(const SharedState& shraed_state)
{
string key = getKey(shraed_state);
if (m_Flyweights.find(key) == m_Flyweights.end())
{
std::cout << "FlyweightFactory:没有找到需要的享元,创建一个新的." << std::endl;
m_Flyweights.insert({ key,shraed_state });
}
else
{
std::cout << "FlyweightFactory:返回一个现有的享元" << std::endl;
}
return &m_Flyweights.at(key);
}
void listFlyWeights() const
{
int count = m_Flyweights.size();
std::cout << "\nFlyweightFactory:我有" << count << "个享元:\n";
for (std::pair<std::string, Flyweight> item : m_Flyweights)
{
std::cout << item.first << "\n";
}
}
};
class CarInfoContext
{
private:
Flyweight* m_flyWeight = nullptr;//内部状态
UniqueState m_uniqueState; //外部状态
public:
CarInfoContext(Flyweight* flyWeight, const UniqueState* unique_state) :
m_flyWeight(flyWeight), m_uniqueState(*unique_state) {}
void operation()
{
m_flyWeight->operation(m_uniqueState);
}
};
//Client
class PoliceCarDatabase
{
private:
std::list<CarInfoContext*> carInfoDatabase;
public:
~PoliceCarDatabase()
{
for (auto item : carInfoDatabase)
delete item;
}
void addCarToPoliceDatabase(FlyweightFactory& ff,
const string& owner,const string& plates,
const string& brand,const string& model,const string& color)
{
std::cout << "\n客户端:添加车辆信息到数据库\n";
Flyweight* flyWeight = ff.getFlyWeight({ brand,model,color });
UniqueState uniqueState(owner, plates);//外部状态
carInfoDatabase.push_back(new CarInfoContext(flyWeight, &uniqueState));
std::cout << "\n客户端:数据库当前状态:\n";
for (auto item : carInfoDatabase)
{
item->operation();
}
}
};
int main()
{
FlyweightFactory factory({
SharedState("奔驰","GLC","白色"),
SharedState("奥迪","A7","红色"),
SharedState("五菱宏光","X1","黑色")
});
factory.listFlyWeights();
PoliceCarDatabase database;
database.addCarToPoliceDatabase(factory,
"李", "豫C998", "五菱宏光", "X1", "黑色");
factory.listFlyWeights();
database.addCarToPoliceDatabase(factory,
"李", "豫C994545", "比亚迪", "唐EV", "蓝色");
database.addCarToPoliceDatabase(factory,
"李", "豫C997676", "五菱宏光", "X1", "黑色");
factory.listFlyWeights();
}