Flyweight 享元模式简介与 C# 示例【结构型6】【设计模式来了_11】

〇、简介

1、什么是享元模式?

一句话解释:

**  将相似或同类的对象共享同一个对象,将这些对象暂存在列表中,使用时直接取出,避免每次使用时都要新建浪费资源。**

享元模式的目的是减少对象的创建,通过共享对象来提高系统的性能。享元设计模式将对象的实例分为两种:内部共享对象和外部共享对象。内部共享对象是由享元类创建的,可以被多个对象共享。外部共享对象是由客户端创建的,不能被多个对象共享。

官方意图描述:运用共享技术有效地支持大量细粒度的对象。

一个比喻:(学校的足球场和篮球馆)

**  首先对于学校的足球场和篮球馆有共享属性,当有足球比赛时,就对应的是足球场,有篮球比赛时,对应的就是篮球馆,不会每次比赛都去新建场馆。**

2、享元模式的优缺点和适用场景

优点:

  • 减少对象的创建:享元设计模式通过共享对象来减少对象的创建,这样可以减少内存占用从而提高系统的性能。
  • 简化客户端代码:客户端只需要与享元接口交互,而不需要了解底层的具体实现细节,从而简化了客户端的代码。
  • 提高系统的扩展性:享元设计模式通过共享对象来提高系统的扩展性,这样可以方便地添加新的共享对象。
  • 降低系统的耦合度:享元模式将对象的创建和使用分离开来,使得系统的各个部分之间的耦合度降低,提高了系统的可维护性和可扩展性。

缺点:

  • 增加了系统的复杂性:享元模式需要引入额外的享元工厂类和享元类,增加了系统的复杂性。
  • 可能增加系统的维护成本:享元模式可能会增加系统的维护成本,因为需要考虑如何更新对象、如何维护对象、如何测试对象等问题。
  • 影响系统的稳定性:当新增类型时,需要对享元工厂进行修改,可能导致系统的异常,同时也会增加额外的维护成本。

适用场景:

  • 对象池:当需要频繁创建和销毁相似的对象时,可以使用享元模式将这些对象缓存在一个池中,以便重复使用。这样可以减少对象的创建和销毁成本,提高性能。
  • 文字编辑器:在文字编辑器中,每个字符都可以作为一个独立的对象来表示。但对于相同的字符,我们不必为每个出现的位置都创建一个新对象,而是可以共享同一个对象实例,从而节省内存空间。
  • 缓存系统:在缓存系统中,经常需要缓存大量的数据对象。通过使用享元模式,可以共享相同的数据对象,减少内存占用,并提高缓存的效率。
  • 游戏开发:在游戏中,特别是大规模多人在线游戏(MMOG)中,存在大量相似的对象,如玩家、怪物、道具等。通过使用享元模式,可以共享这些相似对象之间的公共数据,并且只需存储各个对象的变化部分,从而节省内存占用。

一、通过简单的示例代码实现享元模式

如下示例代码,通过一个字典来存储类的实例,如果 key 标识的实例第二次调用时,就直接从字典中取,不再重新创建:

复制代码
// 测试一下
class Program
{
    static void Main(string[] args)
    {
        Flyweight flyweight = FlyweightFactory.GetFlyweight("Flyweight");
        Flyweight flyweight1 = FlyweightFactory.GetFlyweight("Flyweight1");
        Flyweight flyweight2 = FlyweightFactory.GetFlyweight("Flyweight2");
        flyweight.Operation();
        flyweight1.Operation();
        flyweight2.Operation();
        Console.ReadLine();
    }
}
public class FlyweightFactory
{
    private static Dictionary<string, Flyweight> flyweightDictionary = new Dictionary<string, Flyweight>();
    public static Flyweight GetFlyweight(string key)
    {
        if (flyweightDictionary.ContainsKey(key))
        {
            return flyweightDictionary[key];
        }
        else
        {
            switch (key) 
            {
                case "Flyweight1":
                    ConcreteFlyweight1 flyweight1 = new ConcreteFlyweight1();
                    flyweightDictionary[key] = flyweight1;
                    return flyweight1;
                case "Flyweight2":
                    ConcreteFlyweight2 flyweight2 = new ConcreteFlyweight2();
                    flyweightDictionary[key] = flyweight2;
                    return flyweight2;
                default:
                    Flyweight flyweight = new Flyweight();
                    flyweightDictionary[key] = flyweight;
                    return flyweight;
            }
        }
    }
}
public class Flyweight
{
    public virtual void Operation()
    {
        Console.WriteLine("Operation is performed by Flyweight.");
    }
}
public class ConcreteFlyweight1 : Flyweight
{
    public override void Operation()
    {
        Console.WriteLine("ConcreteFlyweight1 is performing the operation.");
    }
}
public class ConcreteFlyweight2 : Flyweight
{
    public override void Operation()
    {
        Console.WriteLine("ConcreteFlyweight2 is performing the operation.");
    }
}

若后续需要添加新的享元实例ConcreteFlyweight3,就可以直接继承类Flyweight,但同时也需要在FlyweightFactory工厂类中添加对应的实例判断代码。

二、结构

根据上一章节中的示例代码,可以得结构图:

Flyweight:描述一个接口,通过这个接口 flyweight 可以接受并作用于外部状态。

ConcreteFlyweight:实现 Flyweight 接口,并为内部状态(如果有的话)增加存储空间。Concrete-Flyweight 对象是可共享的。它所存储的状态必须是内部的,即它必须独立于 ConcreteFlyweight 对象的场景。

FlyweightFactory:创建并管理flyweight 对象;确保合理地共享 flyweight。当用户请求一个 flyweight 时,FlyweightFactory 对象提供一个已创建的实例或者创建一个(如果不存在的话)。

Client:维持一个对 flyweight 的引用;计算或存储一个或多个 flyweight 的外部状态。

三、相关模式

Flyweight 享元模式通常和 Composite 组合模式结合起来,用共享叶结点的有向无环图实现一个逻辑上的层次结构。

通常,最好用 flyweight 实现 State 状态模式和Strategy 策略模式对象。

相关推荐
AI行业学习6 小时前
.NET Framework 3.5 SP1 完整离线包【2026.5.31】
.net
学以智用11 小时前
.NET Core 完整特性速查表(终极版)
后端·.net
cdbqss112 小时前
VB2026 动态生成工具栏类 BqGetToolStrip
数据库·oracle·开源·.net·学习方法·教育电商·basic
宝桥南山13 小时前
Microsoft Agent Framework(MAF) - 如何将workflow或者A2A client转换成一个AI Agent
microsoft·ai·微软·aigc·.net·.netcore
三天不学习2 天前
YOLO + .NET 10 快速入门:从零搭建实时目标检测应用
yolo·目标检测·.net
0x00072 天前
译 Anders Hejlsberg 谈 C# 与 .NET
开发语言·c#·.net
AI行业学习2 天前
.NET Framework 3.5 SP1 完整离线包(2029.5.29)
开发语言·windows·.net
AI行业学习2 天前
.NET Framework 3.5 官方离线包下载+完整安装教程【2026.5.29】
windows·.net·notepad++
我是唐青枫2 天前
C#.NET YARP 服务发现实战:接入 Consul 和 Kubernetes 动态发现后端服务
c#·服务发现·.net
一个帅气昵称啊2 天前
NetcoreKevin:.NET 企业级智能体管理框架
.net