【设计模式&C#】享元模式(用于解决多次创建对象而导致的性能问题)

一种结构型设计模式。

特点是通过共享内部状态来减少对象的数量,从而降低内存使用和提高性能。

优点:

  1. 大幅减少对象的数量,减少了内存的使用,提高了性能;
  2. 支持更多颗粒度对象,而不会导致内存溢出;
  3. 可以与对象池技术结合,进一步提高对象池的复用效率。

缺点:

  1. 为了实现享元模式,需要将对象的状态分为内部状态和外部状态,提高了系统的复杂性;
  2. 享元对象被多个线程共享,可能会导致性能安全问题;

适用场景:

  1. 需要管理大量颗粒度对象;
  2. 对象大部分状态可以被共享;
  3. 共享对象时可以显著减少内存的使用;
  4. 外部状态可以通过客户端代码临时传入。

示例:

cs 复制代码
public abstract class MoTor
{   
    //内部状态
    public string color;

    public MoTor(string color)
    {
        this.color = color;
    }

    /// <summary>
    /// 外部状态方法,account属于账号(外部状态)
    /// </summary>
    /// <param name="account"></param>
    public abstract void GetMoTor(int account);
}
cs 复制代码
public class MTMoTor : MoTor
{   
    public MTMoTor(string color): base(color)
    {

    }

    public override void GetMoTor(int account)
    {
        Debug.Log("用户" + account + "获取了一辆颜色为:" + color + "的MTMoTor");
    }
}
cs 复制代码
public class OPMoTor : MoTor
{   
    public OPMoTor(string color): base(color)
    {

    }

    public override void GetMoTor(int account)
    {
        Debug.Log("用户" + account + "获取了一辆颜色为:" + color + "的OPMoTor");
    }
}
cs 复制代码
/// <summary>
/// 享元模式工厂
/// </summary>
public class MoTorFlyWeightFactory
{   
    //motor示例管理容器
    private Dictionary<string, MoTor> motorMaps = new Dictionary<string, MoTor>();

    public MoTor GetMotor(string color, MoTorType moTorType)
    {   
        string key = color + "_" + moTorType.ToString();

        if (motorMaps.ContainsKey(key))
        {
            return motorMaps[key];
        }    
        else
        {
            MoTor moTor = null;

            switch (moTorType)
            {
                case MoTorType.MTMoTor:
                    moTor = new MTMoTor(color);
                    break;
                case MoTorType.OPMoTor:
                    moTor = new OPMoTor(color);
                    break;
                default:
                    Debug.Log("目前没有这种车型");
                    return null;
            }

            motorMaps[key] = moTor;

            return moTor;
        }
    }

    public void SearchMaps()
    {
        foreach(string key in motorMaps.Keys)
        {
            Debug.Log(key);
        }
    }
}
cs 复制代码
public enum MoTorType
{
    MTMoTor,
    OPMoTor,
}
cs 复制代码
public class Client
{
    public static void Main(string[] args)
    {
        MoTorFlyWeightFactory moTorFlyWeightFactory = new();

        MoTor mtMotor = moTorFlyWeightFactory.GetMotor("blue", MoTorType.MTMoTor);//生成成功 然后获取到
        MoTor opMotor = moTorFlyWeightFactory.GetMotor("red", MoTorType.OPMoTor);//生成成功,然后获取到

        if(mtMotor != null)
        {
            mtMotor.GetMoTor(111000);//账号111000获取了颜色为blue的MTMoTor
        } 
        if(opMotor != null)
        {
            opMotor.GetMoTor(12345);//账号12345获取了颜色为red的OPMoTor
        }
        
        //遍历实例化容器
        moTorFlyWeightFactory.SearchMaps();
    }
}
相关推荐
玖玥拾4 小时前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
铅笔侠_小龙虾4 小时前
Rust 学习目录
开发语言·学习·rust
云泽8085 小时前
从零吃透 C++ 异常:抛出捕获、栈展开、异常重抛与编码规范详解
开发语言·c++·代码规范
灯澜忆梦5 小时前
GO---可见性规则
开发语言·golang
逝水无殇5 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
这是个栗子6 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
凤凰院凶涛QAQ6 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
研☆香6 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
右耳朵猫AI6 小时前
PHP周刊2026W28 | 安全更新、Laravel 13.18、Twig 3.28
开发语言·php·laravel
second607 小时前
第一部分:快速上手 —— 建立 C++ 基本语法与编程范式
开发语言·c++