零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C 语言基础入门
零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C++ 面向对象
零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C++ 设计模式
零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C++ STL
零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C/C++ 技术杂谈
零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> C/C++ 常用函数
一.享元模式简述
享元模式(Flyweight Pattern)运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。
二.享元模式模式结构
- Flyweight(抽象享元类):通常是一个抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)。
- ConcreteFlyweight(具体享元类):实现了抽象享元类,其实例称为享元对象;在具体享元类中为内部状态提供了存储空间。通常可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。
- UnsharedConcreteFlyweight(非共享具体享元类):并不是所有抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类,当需要一个非共享具体享元类的对象时可以直接通过实例化创建。
- FlyweightFactory(享元工厂类):用于创建并管理享元对象,它针对抽象享元类编程,将各种类型的具体享元对象存储在一个享元池中,享元池一般设计为一个存储“键值对”的集合(也可以是其他类型的集合),可以结合工厂模式进行设计;当用户请求一个具体享元对象时,享元工厂提供一个存储在享元池中已创建的实例或者创建一个新的实例(如果不存在的话),返回新创建的实例并将其存储在享元池中。
三.享元模式优缺点
优点:
- 可以极大减少内存中对象的数量,使得相同或相似对象在内存中只保存一份,从而可以节约系统资源,提高系统性能。
- 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
缺点:
- 享元模式使得系统变得复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
- 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。
四.享元模式适用场景
- 一个系统有大量相同或者相似的对象,造成内存的大量耗费。
- 对象的大部分状态都可以外部化,可以将这些外部状态传入对象中。
- 在使用享元模式时,需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源。因此,应当在需要多次重复使用享元对象时才值得使用享元模式。
五.享元模式案例分析
CS 将玩家分为“恐怖份子”(Terrorists)与“反恐精英”(Counter Terrorists)两个阵营,每个队伍必须在地图上进行多回合的战斗。在“爆破模式”中,T 阵营的任务是在指定时间内装置 C4 并引爆,而 CT 阵营的任务是拆除被装置的 C4。当玩家请求武器时,系统会为其分配所需的武器。
现在,有 n 个玩 CS 的玩家,如果创建 n 个对象(每个玩家一个),这势必会占用大量内存。为了解决这个问题,可以使用享元模式(减少玩家数量),只需要为恐怖分子和反恐精英创建两个对象,在需要时反复使用即可。
六.享元模式内部状态和外部状态
享元对象之所以能做到共享,关键是区分了内部状态和外部状态:
- 内部状态(Intrinsic State):存储在享元对象内部,并且不会随环境改变而改变。因此,内部状态可以共享。
这里的“任务”就是两种类型玩家的内部状态,不会随外部环境的变化而变化。无论在任何环境下,T 的任务永远是装置 C4 并引爆,而 CT 的任务永远是拆除 C4。 - 外部状态(Extrinsic State):随环境改变而改变的、不可以共享的状态。享元对象的外部状态通常由客户端保存,并在享元对象被创建之后,需要使用时再传入到享元对象内部。一个外部状态与另一个外部状态之间是相互独立的。
比如“武器”,每个玩家都可以携带自己选择的任何武器。有的玩家用的是 AK-47,有的则用的是沙漠之鹰。
由于区分了内部状态和外部状态,因此可以将具有相同内部状态的对象存储在享元池中来实现共享。当需要时,将对象从享元池中取出以实现对象的复用。通过向取出的对象注入不同的外部状态,可以得到一系列相似的对象,而这些对象在内存中实际上只存储一份。
七.享元模式代码实现
/************************************************************************/
//@Author:猿说编程
//@Blog(个人博客地址): https://www.codersrc.com/archives/21429.html
//@File:C++ 设计模式 – 享元模式
//@Time:2023/01/31 08:00
//@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
/************************************************************************/
八.猜你喜欢
ChatGPT 3.5 国内中文镜像站免费使用啦
暂无评论内容