3.6.1 定义
运用共享技术有效地支持大量细粒度的对象。
享元模式——运用共享技术有效地支持大量细粒度的对象。享元模式可以避免大量相似类的开销,在软件开发中如果需要生成大量细粒度的类实例来表示数据,如果这些实例除了几个参数外基本上都是相同的,这时候就可以使用享元模式来大幅度减少需要实例化类的数量。如果能把这些参数(指的这些类实例不同的参数)移动类实例外面,在方法调用时将他们传递进来,这样就可以通过共享大幅度地减少单个实例的数目。(这个也是享元模式的实现要领),然而我们把类实例外面的参数称为享元对象的外部状态,把在享元对象内部定义称为内部状态。具体享元对象的内部状态与外部状态的定义为:
内部状态:在享元对象的内部并且不会随着环境的改变而改变的共享部分
外部状态:随环境改变而改变的,不可以共享的状态。
3.6.2 场景模拟
一个文本编辑器中会出现很多字面,使用享元模式去实现这个文本编辑器的话,会把每个字面做成一个享元对象。享元对象的内部状态就是这个字面,而字母在文本中的位置和字体风格等其他信息就是它的外部状态。
3.6.3 场景代码实现
享元类:
/// <summary> /// 抽象享元类,提供具体享元类具有的方法 /// </summary> public abstract class Flyweight { public abstract void Operation(int extrinsicstate); } public class ConcreteFlyweight : Flyweight { //内部状态 private string intrinsicstate; public ConcreteFlyweight(string innerState) { this.intrinsicstate = innerState; } public override void Operation(int extrinsicstate) { Console.WriteLine($"具体实现类:内部状态 {intrinsicstate},外部状态 {extrinsicstate}"); } }
享元工厂类:
/// <summary> /// 享元工厂类,负责创建和管理享元对象 /// </summary> class FlyweightFactory { public Dictionary<string,Flyweight> flyweights = new Dictionary<string,Flyweight>(); public Flyweight GetFlyweight(string key) { if (flyweights.ContainsKey(key)) return flyweights[key]; else { ConcreteFlyweight flyweight = new ConcreteFlyweight(key); flyweights.Add(key, flyweight); return flyweights[key]; } } }
客户端调用类:
class Program { static void Main(string[] args) { //定义外部状态,例如字母的位置等信息 int externalstate = 10; FlyweightFactory factory = new FlyweightFactory(); Flyweight flyweightA = factory.GetFlyweight("A"); flyweightA.Operation(--externalstate); Flyweight flyweightB = factory.GetFlyweight("B"); flyweightB.Operation(--externalstate); Flyweight flyweightC = factory.GetFlyweight("C"); flyweightC.Operation(--externalstate); Flyweight flyweightD = factory.GetFlyweight("D"); flyweightD.Operation(--externalstate); Console.ReadLine(); } }
3.6.4 结构图
3.6.5 享元模式的应用场景
1、系统需要大量相似对象
2、创建这些对象需要花费大量资源
3、状态可分为内在状态和外在状态,可以根据内在状态分为各种组。
4、需要缓冲池的场景
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)