设计模式之享元模式(C++)
作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、享元模式是什么?
享元模式是一种结构型的软件设计模式,通过共享对象的方式,尽可能减少内存占用,从而达到优化的目的。
就像打麻将,同时有10桌在玩,每桌都有4个"八筒",如果建立40个"八筒"对象,那就非常冗余,但如果用享元模式建立一套麻将牌,每桌打出"八筒"时,就调用享元中的"八筒",相当于只用了1个对象,这样即节省了资源,也完成了需求。
上述例子中,桌号和牌号就是享元模式的外蕴状态,如A1八筒,就是A桌的第一个"八筒",A和1是外蕴状态;而卡牌"八筒"本身就是内蕴状态,内蕴是可以共享的。外蕴随环境变化,占用资源也少的多,往往只是简单的数据结构。
享元模式的优点:
- 减少资源浪费。共享资源极大程度降低了系统的资源消耗。
- 提高系统运行效率。当资源过度使用时,系统效率会大受影响。
享元模式的缺点:
- 维护共享对象,需要额外开销。
- 系统复杂度提高。运行享元,除了内外状态,还有线程方面都要充分考虑。
二、享元模式
2.1 结构图
客户端即Main主函数,调用享元工厂获取享元对象。

2.2 代码示例
场景描述:模拟组合一套八卦牌。
//Flyweight.h
/****************************************************/
#pragma once
#include
#include
#include
#include using namespace std;// 抽象享元
class Flyweight
{
public:// 操作virtual void operation() = 0;};// 具体享元
class ConcreteFlyweight : public Flyweight
{
public:// 构造函数ConcreteFlyweight(string name) : m_name(name) {}// 操作virtual void operation() {cout << "打出" << m_name << endl;}private:string m_name;
};// 享元工厂
class FlyweightFactory
{
public:// 析构函数~FlyweightFactory() {for (auto it : flyweights) {cout << "销毁" << it.first << "牌" << endl;delete it.second;it.second = nullptr;}flyweights.clear();}// 获取享元Flyweight* getFlyweight(string name) {// 若没有,则创建if (flyweights.find(name) == flyweights.end()) {cout << "创建" << name << "牌" << endl;flyweights[name] = new ConcreteFlyweight(name);}else {cout << "已有" << name << "牌" << endl;}return flyweights[name];}private:std::unordered_map flyweights;
};
//main.cpp
/****************************************************/
#include
#include
#include "Flyweight.h"using namespace std;int main()
{FlyweightFactory *factory = new FlyweightFactory();Flyweight* f1 = factory->getFlyweight("乾");Flyweight* f2 = factory->getFlyweight("坤");Flyweight* f3 = factory->getFlyweight("坎");Flyweight* f4 = factory->getFlyweight("离");Flyweight* f5 = factory->getFlyweight("震");Flyweight* f6 = factory->getFlyweight("巽");Flyweight* f7 = factory->getFlyweight("艮");Flyweight* f8 = factory->getFlyweight("兑");Flyweight* f9 = factory->getFlyweight("坤");f3->operation();delete factory;factory = nullptr;return 0;
}
程序结果如下。

八卦的八个牌在初次调用时因为不存在所以创建,而第九次调用已有的坤,便不用new了。删除工厂后,析构函数别忘了将new的数据delete。
三、总结
我尽可能用较通俗的话语和直观的代码例程,来表述我对享元模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解享元模式。
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
