1. 概述
本文将深入探讨享元设计模式。该模式主要用于减少内存占用,同时在对象创建成本较高的应用中提升性能。
简单来说,享元模式的核心是一个工厂,它通过存储已创建的对象来实现复用。每次请求对象时,工厂会先查找该对象是否已存在:
- ✅ 若存在:直接返回现有对象
- ❌ 若不存在:创建新对象、存储后返回
享元对象的状态由两部分组成:
- 内在状态:不可变部分,被相似对象共享
- 外在状态:可变部分,由客户端代码操作
⚠️ 关键点:享元对象必须是不可变的!任何状态操作都必须通过工厂执行。
2. 实现方案
模式的核心组件包括:
- 接口:定义客户端可对享元对象执行的操作
- 具体实现类:实现接口的类
- 工厂类:处理对象实例化和缓存
下面我们逐一实现这些组件。
2.1. 车辆接口
首先创建 Vehicle
接口。作为工厂方法的返回类型,需暴露所有必要方法:
public void start();
public void stop();
public Color getColor();
2.2. 具体车辆类
接下来实现 Car
类作为具体车辆。它需实现接口所有方法,状态包含引擎和颜色字段:
private Engine engine;
private Color color;
2.3. 车辆工厂
最后创建 VehicleFactory
。由于车辆创建成本高昂,工厂将为每种颜色只创建一个实例。使用 Map 作为简单缓存:
private static Map<Color, Vehicle> vehiclesCache
= new HashMap<>();
public static Vehicle createVehicle(Color color) {
Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> {
Engine newEngine = new Engine();
return new Car(newEngine, newColor);
});
return newVehicle;
}
注意:客户端代码只能通过传递颜色参数影响对象的外在状态。
3. 应用场景
3.1. 数据压缩
享元模式通过最大化数据共享来减少内存使用,因此非常适合无损压缩算法。此时每个享元对象相当于指针,其外在状态是上下文相关信息。
典型例子是文字处理器:
- 每个字符是享元对象
- 共享渲染所需数据
- 仅字符位置占用额外内存
3.2. 数据缓存
现代应用普遍使用缓存提升响应速度。享元模式与缓存核心概念相似,可很好地满足此需求。
但需注意:
- ✅ 享元模式适用于对象复用
- ❌ 与通用缓存在复杂度和实现上存在差异
4. 总结
本文系统讲解了 Java 中的享元设计模式,并分析了其典型应用场景。所有示例代码可在 GitHub 项目 中获取。