享元模式(Flyweight Pattern)
一、概念
享元模式(Flyweight Pattern)是 "资源池技术"实现方式,主要用于减少创建对象的数量
,以减少内存占用和提高性能。
-
模式动机:在创建大量对象时,有可能会造成内存溢出,享元模式把其中共同的部分抽象出来,保存在内存中,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
-
解决思路:复用对象最简单的方式是,用一个 HashMap 来存放每次新生成的对象。每次需要一个对象的时候,先到 HashMap 中看看有没有,如果没有,再生成新的对象,然后将这个对象放入 HashMap 中。
- 享元模式通常需要和其他模式一起联用,几种常见的联用方式如下:
-
- 享元模式的享元工厂类中通常
提供一个静态的工厂方法
用于返回享元对象,使用简单工厂模式
来生成享元对象 - 在一个系统中,
通常只有唯一一个享元工厂
,因此可以使用单例模式
进行享元工厂类的设计。 - 享元模式可以
结合组合模式形成复合享元模式
,统一对多个享元对象设置外部状态。
- 享元模式的享元工厂类中通常
二、适用场景
有大量相同或者相似的对象
,造成内存的大量耗费- 对象的
大部分状态都可以外部化
,可以将这些外部状态传入对象中。 - 需要缓冲池的场景
- 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式
三、参与者
- Flyweight(抽象享元角色) :
享元对象的抽象基类或者接口
,声明所有具体享元角色需要实现的方法,这些方法可以向外界提供对象的内部状态,设置外部状态
。- 内部状态(intrinsic):是
享元对象可共享的属性
,存储在享元对象内部并且不会随环境改变而改变。 - 外部状态(extrinsic):是
对象得以依赖的一个标记
,是随环境改变而改变的、不可以共享的状态。
- 内部状态(intrinsic):是
-
ConcreteFlyweight( 具体享元角色):
Flyweight的具体实现
,实现抽象角色定义的方法。 为内部状态提供成员变量进行存储
-
UnsharedConcreteFlyweigh( 非共享的享元角色):
不能被共享的子类
可以设计为非共享享元类 - FlyweightFactory(享元工厂角色):
负责管理享元对象池和创建享元对象
,就是构造一个池容器,同时提供从池中获得对象的方法
,- 当请求获取一个享元对象时,享元工厂判断是否存在该享元对象,如果存在则返回;如果不存在的话,则创建一个新的享元对象,保存到池容器中,然后返回给请求者。
享元池一般设计成键值对
。享元模式一般都是和工厂模式一起出现
四、代码例子
(一)单纯享元
工具箱内可以放置多个型号的扳手,当需要用大扳手时我们会买一个放在工具箱内,需要中号或小号的扳手时再买小号、中号的扳手放在工具箱内,如果朋友需要大号的扳手则可以直接从工具箱中拿出使用,但他需要用中号或小号扳手时,就需要先去五金店买一把中号或小号扳手放在工具箱内。这样其他人在使用扳手时直接从工具箱内拿出来使用就可以。
(二)复合享元
工具箱内可以放置多个型号的扳手,但是由于扳手总是丢失,所以每个人都有私人工具箱且不可外借,这个扳手不管你是装配还是维修都可以使用,如果没有合适的扳手需要自己去五金店买。
五、UML图
(一)单纯享元
(二)复合享元
六、模式思想
相同的对象共享使用。
单纯享元是开放式共享,所有对象均可以分享使用;单纯享元的特点是所有元素都是共享的;
复合享元是区分式共享,比如说同一小组或好朋友可以共享,陌生人不共享,不同小组之间不共享;复合享元角色对象是不共享的,但是一个复合享元内部对象可以划分为多个共享享元表示;
七、优缺点
(一)优点
- 极大
减少内存中对象的数量
,相同或相似对象内存中只存一份,降低程序内存的占用,增强程序的性能。
- 外部状态相对独立,不影响内部状态
(二)缺点
- 提高了系统复杂性,需要分离出外部状态和内部状态,而且外部状态不应该随内部状态改变而改变,否则导致系统的逻辑混乱。
- 为了节省内存,共享了内部状态,分离出外部状态,而读取外部状态使运行时间变长。用时间换取了空间。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了