设计模式之享元模式(C++)

简介: 设计模式之享元模式(C++)

一、享元模式是什么?

      享元模式是一种结构型的软件设计模式,通过共享对象的方式,尽可能减少内存占用,从而达到优化的目的。


      就像打麻将,同时有10桌在玩,每桌都有4个"八筒",如果建立40个"八筒"对象,那就非常冗余,但如果用享元模式建立一套麻将牌,每桌打出"八筒"时,就调用享元中的"八筒",相当于只用了1个对象,这样即节省了资源,也完成了需求。


      上述例子中,桌号和牌号就是享元模式的外蕴状态,如A1八筒,就是A桌的第一个"八筒",A和1是外蕴状态;而卡牌"八筒"本身就是内蕴状态,内蕴是可以共享的。外蕴随环境变化,占用资源也少的多,往往只是简单的数据结构。


      享元模式的优点:


  1. 减少资源浪费。共享资源极大程度降低了系统的资源消耗。
  2. 提高系统运行效率。当资源过度使用时,系统效率会大受影响。

     享元模式的缺点:


  1. 维护共享对象,需要额外开销。
  2. 系统复杂度提高。运行享元,除了内外状态,还有线程方面都要充分考虑。

二、享元模式

2.1 结构图

      客户端即Main主函数,调用享元工厂获取享元对象。

2.2 代码示例

      场景描述:模拟组合一套八卦牌。

//Flyweight.h
/****************************************************/
#pragma once
#include <iostream>
#include <unordered_map>
#include <vector>
#include <list>
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<string, Flyweight*> flyweights;
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#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。

三、总结

      我尽可能用较通俗的话语和直观的代码例程,来表述我对享元模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解享元模式。

      如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

相关文章
|
1月前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
37 4
|
2月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
66 0
|
2月前
|
设计模式 算法 C++
【C++ 泛型编程 进阶篇】C++元模板编程与设计模式的结合应用教程(二)
【C++ 泛型编程 进阶篇】C++元模板编程与设计模式的结合应用教程
30 0
|
2月前
|
设计模式 存储 uml
C++ 设计模式实战:外观模式和访问者模式的结合使用,派生类访问基类的私有子系统
C++ 设计模式实战:外观模式和访问者模式的结合使用,派生类访问基类的私有子系统
30 1
|
2月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
55 0
|
17天前
|
设计模式 存储 Java
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
|
26天前
|
设计模式 存储 Java
小谈设计模式(27)—享元模式
小谈设计模式(27)—享元模式
|
2月前
|
设计模式 算法 中间件
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
【C++ 可调用对象的应用】C++设计模式与现代编程技巧:深入可调用对象的世界
126 1
|
2月前
|
设计模式 机器学习/深度学习 算法
C++设计模式新篇章:掌握状态委托
C++设计模式新篇章:掌握状态委托
75 0
|
2月前
|
设计模式 算法 C++
从 C++ 优化状态机实现:结合设计模式的实用指南
从 C++ 优化状态机实现:结合设计模式的实用指南
69 1