• C++ 享元模式


    什么是享元模式?

    • 享元模式是一种结构型设计模式,实现了在较少内存开销的同时,又支持了大量的对象,主要在资源有限的情况下,对创建大量对象行为的一种约束行为;

    享元模式的适用特征

    • 当程序中有大量的相同对象
    • 这些对象消耗了大量的内存
    • 这些对象的状态可以外部表现
    • 这些对象可以进行分组

    如何理解享元模式

    我们这里以聊天软件为例,当我们和好友在不同的群聊中,同一个头像会出现在多个地方,由于图片都相比较耗费资源。我们可以通过用户的ID维护一个头像的Map,这时候,除了第一次是图片加载到内存中,后续所有的头像都是拿到了当前这个头像的引用,进而减小了整个程序的内存占用。

    代码描述

    我们这里用户头像为例子

    • 首先需要一个图像的接口类
    /* 抽象享元类接口 */
    class I_Image {
    public:
    	virtual ~I_Image(){};
    	virtual void Operation() = 0;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 创建具体的用户头像
    class UserHeader : public I_Image {
    private:
    	string str;
    
    public:
    	UserHeader(string str) { this->str = str; }
    	void Operation() { cout << "user header image is : " << str << endl; }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 通过一个享元工厂类来维护数据的拿取及创建
    class ImageFactory {
    public:
    	ImageFactory() {}
    	std::shared_ptr<I_Image> GetImage(string obj)
    	{
    		std::shared_ptr<I_Image> item_image = nullptr;
    		//如果没有找到对应的图片则创建
    		if (image_map_.count(obj) == 0) {
    			cout << "No find user header and Create Header= " << obj << endl;
    			item_image = std::make_shared<UserHeader>(obj);
    			image_map_.insert(std::map<std::string, std::shared_ptr<I_Image>>::value_type(obj, item_image));
    		}
    		return image_map_[obj];
    	}
    	int GetImageMapSize() {
    	    return image_map_.size(); 
    	}
    private:
    	map<string, std::shared_ptr<I_Image>> image_map_;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 这时候我们随机创建几个头像,来测试一下
    int main()
    {
    	std::shared_ptr<ImageFactory> image_factory = std::make_shared<ImageFactory>();
    	std::shared_ptr<I_Image>      header_1      = image_factory->GetImage("zhangsan");
    	std::shared_ptr<I_Image>      header_2      = image_factory->GetImage("lisi");
    	std::shared_ptr<I_Image>      header_3      = image_factory->GetImage("zhangsan");
    	std::shared_ptr<I_Image>      header_4      = image_factory->GetImage("xiaoming");
    	std::shared_ptr<I_Image>      header_5      = image_factory->GetImage("xiaohong");
    	std::shared_ptr<I_Image>      header_6      = image_factory->GetImage("lisi");
    	cout << "======================================================"<< endl;
    	cout << "image_factory size = " << image_factory->GetImageMapSize() << endl;
    	cout << "======================================================" << endl;
    	header_1->OutPutImage();
    	header_2->OutPutImage();
    	header_3->OutPutImage();
    	header_4->OutPutImage();
    	header_5->OutPutImage();
    	header_6->OutPutImage();
    	return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 输出结果如下
      在这里插入图片描述

    享元模式的思考

    优点:

    • 减少了内存的开销及占用,同一个类型的对象只保留一份;

    缺点:

    • 可能会牺牲运行速度换取减少空间的开销;
    • 由于要区分出内部状态和外部状态,会使得代码变得更加复杂,晦涩;

    总结:

    • 如果你的程序没有遇到内存容量不足的问题, 不建议使用该模式。

    享元模式与其他模式的比较

    • 享元模式和单例模式有类似,但享元模式对象是不可以改变的,单例模式对象是可变的;享元模式运行一个程序内部有多个享元类的实体,内部的状态可以相同或不同。
  • 相关阅读:
    java毕业设计游戏资讯网站Mybatis+系统+数据库+调试部署
    从扫码登录的原理分析QQ大量被盗事件
    高速路标迎来“新面貌”
    1.3 统计学习方法的三要素
    ADAudit Plus:提升企业安全的不可或缺的审计解决方案
    Three光线投射实例
    比较方法equals( )、==以及CompareTo
    入行数字IC验证后会做些什么?需要哪些必备技能?
    阿里巴巴面试题- - -JVM篇(十七)
    基于Java web的电动车销售平台 毕业设计-附源码201524
  • 原文地址:https://blog.csdn.net/u013052326/article/details/126213025