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. 适用场景:优先在对象数量多、创建成本高、内部状态稳定的场景中使用。

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

相关推荐
new_daimond3 小时前
设计模式-策略模式深度分析
设计模式·策略模式
辞去归来兮4 小时前
观察者模式 VS. 发布-订阅者模式
设计模式
一叶难遮天7 小时前
Android面试指南(八)
java·设计模式·数组·hashmap·string·android面试·匿名内部类
星空寻流年16 小时前
设计模式第一章(建造者模式)
java·设计模式·建造者模式
蒋星熠17 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
至此流年莫相忘20 小时前
设计模式:策略模式
设计模式·策略模式
ytadpole21 小时前
揭秘设计模式:命令模式-告别混乱,打造优雅可扩展的代码
java·设计模式
努力也学不会java1 天前
【设计模式】 外观模式
设计模式·外观模式
bikong71 天前
享元模式,用Qt/C++绘制森林
享元模式