101、23种设计模式之享元模式(10/23)

一、定义

享元模式是一种结构型设计模式,通过共享技术减少相似对象的内存占用,尤其适用于存在大量细粒度对象的场景。其核心思想是将对象状态划分为:

  • 内部状态(Intrinsic State):可共享的、不随环境变化的部分(如字形信息、颜色、形状等)。
  • 外部状态(Extrinsic State):不可共享的、随环境变化的部分(如位置、大小、用户数据等)。

通过分离状态并共享内部状态,享元模式显著减少对象数量,降低内存消耗。

二、应用场景

1.图形渲染

  • 场景:游戏或图形编辑器中需渲染大量相似对象(如树木、子弹、文本字符)。

  • 优化:将通用属性(如网格、贴图)作为内部状态共享,仅动态传递位置、颜色等外部状态。

  • 示例:森林渲染中,所有树木共享同一网格和贴图数据,仅位置和高度不同。

2.文本编辑器

  • 场景:处理大量重复字符(如长文档中的空格、标点)。
  • 优化:每个字符对象共享字形信息,仅存储位置、字体等外部状态。
  • 案例:Java字符串常量池通过共享字符串对象减少内存占用。

3.数据库连接池

  • 场景:高并发应用中频繁创建/销毁数据库连接。
  • 优化:连接池管理共享连接对象,避免重复创建开销。
  • 代码片段(C#):
csharp 复制代码
public class ConnectionPool {
    private static Queue<DbConnection> _pool = new Queue<DbConnection>();
    public static DbConnection GetConnection() {
        if (_pool.Count == 0) return new DbConnection();
        return _pool.Dequeue();
    }
    public static void ReleaseConnection(DbConnection conn) {
        _pool.Enqueue(conn);
    }
}

4.游戏开发

  • 场景:管理大量相似游戏对象(如敌人、道具)。
  • 优化:共享对象类型(如敌人类型A)的公共属性(攻击力、模型),仅动态更新位置、生命值等外部状态。

三、优缺点

1.优点

  1. 显著减少内存占用,提升性能。
  2. 降低对象创建开销,提高响应速度。
  3. 适用于高并发或资源受限场景。

2.缺点

  1. 需分离内部/外部状态,增加逻辑复杂度。
  2. 需维护享元池,增加系统资源消耗。
  3. 共享对象需设计为不可变,限制灵活性。

四、C# 示例代码

csharp 复制代码
using System;
using System.Collections.Generic;

// 抽象享元接口
public interface IShape {
    void Draw(int x, int y, string color);
}

// 具体享元:圆形(共享形状,颜色和位置为外部状态)
public class Circle : IShape {
    private string _type = "Circle";
    public void Draw(int x, int y, string color) {
        Console.WriteLine($"Drawing a {_type} at ({x},{y}) with color {color}");
    }
}

// 享元工厂
public class ShapeFactory {
    private Dictionary<string, IShape> _shapes = new Dictionary<string, IShape>();
    public IShape GetShape(string shapeType) {
        if (!_shapes.ContainsKey(shapeType)) {
            _shapes[shapeType] = shapeType switch {
                "Circle" => new Circle(),
                _ => throw new ArgumentException("Shape not supported")
            };
        }
        return _shapes[shapeType];
    }
}

// 客户端代码
public class Program {
    public static void Main() {
        ShapeFactory factory = new ShapeFactory();
        IShape circle1 = factory.GetShape("Circle");
        circle1.Draw(10, 20, "Red");    // 输出: Drawing a Circle at (10,20) with color Red
        IShape circle2 = factory.GetShape("Circle");
        circle2.Draw(30, 40, "Blue");   // 输出: Drawing a Circle at (30,40) with color Blue
        Console.WriteLine(circle1 == circle2); // 输出: True(共享同一实例)
    }
}

五、关键点总结

  1. 状态分离:明确区分内部状态(共享)和外部状态(动态传递)。
  2. 享元工厂:通过工厂管理共享对象,避免重复创建。
  3. 不可变性:共享对象内部状态需设计为不可变,确保线程安全。
  4. 适用场景:优先在对象数量多、创建成本高、内部状态稳定的场景中使用。

享元模式通过精细化的状态管理,在内存优化与系统复杂度之间取得平衡,是处理高并发、资源受限场景的有效工具。

相关推荐
Tt有了t19 小时前
设计模式速查
java·python·设计模式
一条Go20 小时前
四个进程,一把锁:Alioth 的告警评测为什么不需要消息队列
后端·设计模式·架构
一缕82年的清风1 天前
被中产唾弃的“十元快剪”,藏着最狠的极客工程学
人工智能·设计模式
是2的10次方啊1 天前
设计模式与生活⑫:周报又到手,别从空白开始
设计模式
拆房老料2 天前
DeepSeek Super-agent 架构解析:从单任务 Agent 到持续运行的任务系统
人工智能·设计模式·系统架构
工一木子2 天前
设计模式与生活⑩:地铁没变,你换了个状态
设计模式
是2的10次方啊2 天前
设计模式与生活⑪:地铁里被打扰,别总靠自己硬扛
设计模式
高晶3 天前
SPMI 控制器 RTL 设计与验证新手入门
设计模式·程序员·架构
geovindu3 天前
rust:N-Barrier Pattern
开发语言·后端·设计模式·rust·屏障模式·并发型模式
顧棟3 天前
OpenAPI 网关:鉴权 + 流量治理 一体化设计方案与实现
java·spring boot·设计模式