设计模式之享元模式(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。

三、总结

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

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

相关文章
|
7月前
|
设计模式 存储 Java
23种设计模式,享元模式的概念优缺点以及JAVA代码举例
【4月更文挑战第6天】享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享技术有效地支持大量细粒度对象的重用。这个模式在处理大量对象时非常有用,特别是当这些对象中的许多实例实际上可以共享相同的状态时,从而可以减少内存占用,提高程序效率
110 4
|
3月前
|
设计模式 Java
Java设计模式-享元模式(12)
Java设计模式-享元模式(12)
|
4月前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
5月前
|
设计模式 C++
C++一分钟之-设计模式:工厂模式与抽象工厂
【7月更文挑战第14天】设计模式是解决软件设计问题的通用方案。工厂模式与抽象工厂模式是创建型模式,用于对象创建而不暴露创建逻辑。工厂模式推迟实例化到子类,但过度使用会增加复杂性。抽象工厂则创建相关对象族,但过度抽象可能造成不必要的复杂度。两者均应按需使用,确保设计灵活性。代码示例展示了C++中如何实现这两种模式。
49 3
|
5月前
|
设计模式 安全 C++
C++一分钟之-C++中的设计模式:单例模式
【7月更文挑战第13天】单例模式确保类只有一个实例,提供全局访问。C++中的实现涉及线程安全和生命周期管理。基础实现使用静态成员,但在多线程环境下可能导致多个实例。为解决此问题,采用双重检查锁定和`std::mutex`保证安全。使用`std::unique_ptr`管理生命周期,防止析构异常和内存泄漏。理解和正确应用单例模式能提升软件的效率与可维护性。
70 2
|
5月前
|
设计模式 存储 JavaScript
js设计模式【详解】—— 享元模式
js设计模式【详解】—— 享元模式
73 6
|
6月前
|
设计模式 缓存 Java
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
|
6月前
|
设计模式 存储 Java
Java设计模式之享元模式详解
Java设计模式之享元模式详解
|
7月前
|
设计模式 开发框架 算法
C++中的设计模式:基本概念与应用
C++中的设计模式:基本概念与应用
75 2
|
6月前
|
设计模式
享元模式-大话设计模式
享元模式-大话设计模式