设计模式之享元模式
享元模式是结构型模式的一种,其主要思想是运用共享技术支持大量的细粒度对象。
如GOF中提供的例子,文本编辑器中的文字在排版时如果将每个字符看做一个对象,那么一篇不长的文章中也可能包含大量的细粒度对象,占用资源,产生大量的运行时开销。
Flyweight模式解决了这个问题,它通过将字符的内在特征与外部特征区分,抽象出内在特征,像英语文章,标点符合+26个字母,基本可以完成展示,由此大量的减少了对象数量。至于外部属性,如字符的位置,顺序等,则由另外的对象统一管理。
flyweight是一个共享对象,它可以同时在多个场景(context)中使用,并且每个场景中flyweight都会作为独立的对象使用-与非共享对象没有区别。flyweight不能对它所运行的场景做任何假设,这里的关键概念是内部状态和外部状态的区别。内部状态存放在flyweight中,它包含了独立于flyweight场景的信息,这些信息可以使flyweight被共享。而外部状态则取决于flyweight场景,根据场景变化,因而不能被共享。
适用性:
1. 一个程序使用了大量的对象
2. 完全由于使用了大量的对象,造成很大的存储开销
3. 对象大多数状态可变为为外部状态
4. 如果删除外部状态,则可用较少的共享对象取代很多组对象
5. 应用程序不依赖对象标识。由于flyweight可以被共享,对于概念上明显有别对象,标识测试将返回真值
结构:

参与者:
1. FlyWeight
描述一个接口,通过该接口flyweight可以接受并作用于外部状态
2. ConcreteFlyweight
实现Flyweight接口,并为内部空间增加存储空间。ConcreteFlyweight对象必须是可以共享的,其存储状态必须是内部的,即其必须独立于ConcreteFlyweight的场景
3. UnsharedConcreteFlyweight
并非所有Flyweight的子类都需要被共享,在Flyweight的某些层次,UnsharedConcreteFlyweight对象通常将ConcreteFlyweight对象作为子节点
4. FlyweightFactory
创建并管理flyweight
5. Client
维持一个对flyweight的引用
协作:
flyweight执行时所需要的状态必定是内部或者外部的。内部状态存储在ConcreteFlyweight;外部对象则由client对象存储或计算。当用户调用flyweight时,将该状态传递给他
用户不应直接对Flyweight进行实例化,应该通过Flyweight来实现,这样可以实现适度的共享
效果:
减少实例数目节省了空间
效果主要与减少的实例数目,共享内容的多少,以及外部状态是计算还是存储的决定。
实践:
关键是识别出系统中的大量细粒度对象,并从中区分出共享属性和非贡献属性。非共享属性由固定数目的对象来承担,并进行共享。非共享属性,或者通过另外的对象存储,或者通过计算获取,由此可以减少对象数目,和存储空间使用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述