🚩什么是享元设计模式?
享元设计模式(Flyweight Pattern) 是一种 结构型设计模式,它通过 共享对象 来有效支持大量细粒度对象的复用。享元模式的核心思想是 分离对象的内部状态和外部状态,通过共享内部状态来减少内存消耗。
使用场景
当系统需要 创建大量相似对象 时,且这些对象的大部分状态可以外部化。
当对象的 创建成本较高(如占用内存大或初始化时间长)时。
当需要 缓存对象 以提高性能时,如游戏中的粒子系统、文字编辑器中的字符对象等。
🚩享元设计模式的特点
共享对象:通过共享相同内部状态的对象来减少内存消耗。
分离状态:将对象状态分为 内部状态(可共享) 和 外部状态(不可共享)。
工厂管理:通常使用工厂类来管理和复用享元对象。
性能优化:特别适用于需要创建大量相似对象的场景。
🚩享元设计模式的结构
享元模式主要包含以下部分:
Flyweight(抽象享元):定义对象的接口,声明设置外部状态的方法。
ConcreteFlyweight(具体享元):实现抽象享元接口,存储内部状态。
UnsharedConcreteFlyweight(非共享具体享元):不需要共享的子类。
FlyweightFactory(享元工厂):创建和管理享元对象,确保合理地共享享元。
Client(客户端):维护外部状态,并在需要时请求享元对象。
🚩享元设计模式的优缺点
✅ 优点
减少内存消耗:通过共享对象显著减少内存使用。
提高性能:减少了创建对象的数量,降低了系统开销。
灵活性:外部状态可以动态变化,不影响共享的内部状态。
❌ 缺点
增加系统复杂度:需要分离内部状态和外部状态。
线程安全问题:共享对象需要考虑线程安全问题。
不适合所有场景:仅当系统中存在大量相似对象时才有效。
🚩享元设计模式的Java实现
代码地址:GitHub
- 创建 抽象享元 Shape,定义绘制方法。
/**
* @author hanson.huang
* @version V1.0
* @ClassName Shape
* @Description 抽象享元 Shape
* @date 2025/3/24 18:23
**/
public abstract class Shape {
protected String color; // 内部状态
public abstract void draw(int x, int y); // 外部状态作为参数
}
- 创建 具体享元 Circle,实现绘制方法。
/**
* @author hanson.huang
* @version V1.0
* @ClassName Circle
* @Description 具体享元 Circle
* @date 2025/3/24 18:24
**/
public class Circle extends Shape {
public Circle(String color) {
this.color = color;
}
@Override
public void draw(int x, int y) {
System.out.println("draw a color:" + color + " circle x:" + x + " y:" + y);
}
}
- 创建 享元工厂 ShapeFactory,管理享元对象。
/**
* @author hanson.huang
* @version V1.0
* @ClassName ShapeFactory
* @Description 享元工厂 ShapeFactory 管理享元对象
* @date 2025/3/24 18:24
**/
public class ShapeFactory {
private Map<String, Shape> map = new HashMap<>();
public Shape getShape(String key) {
if (!map.containsKey(key)) {
map.put(key, new Circle(key));
System.out.println("create color:" + key + " circle");
}
return map.get(key);
}
}
- 测试享元模式
/**
* @author hanson.huang
* @version V1.0
* @ClassName FlyWeightPattern
* @Description 测试享元模式
* @date 2025/3/24 18:26
**/
public class FlyWeightPattern {
public static void main(String[] args) {
ShapeFactory factory = new ShapeFactory();
Random random = new Random();
String[] colors = {"red", "blue", "green", "white", "black"};
for (int i = 1; i <= 100; i++) {
int x = random.nextInt(colors.length);
Shape shape = factory.getShape(colors[x]);
System.out.print("第" + i + "个圆:");
shape.draw(random.nextInt(2025), random.nextInt(324));
}
}
}
📌 运行结果(部分)
🚩代码总结
抽象享元 Shape 定义绘制方法,颜色作为内部状态。
具体享元 Circle 实现绘制方法,存储颜色(内部状态)。
享元工厂 ShapeFactory 管理共享的圆形对象,按颜色复用。
客户端 维护外部状态(坐标),通过工厂获取享元对象。
🚩总结
享元设计模式 通过共享对象减少内存消耗,适合处理大量相似对象。
核心是 分离内部状态(可共享)和外部状态(不可共享)。
适用于 图形编辑器、游戏开发、文本处理 等需要创建大量相似对象的场景。
✅ 适用场景:
系统需要创建大量相似对象时
对象的大部分状态可以外部化时
需要优化内存使用和提高性能时
Java中很多地方用到了享元设计模式,
Integer
类内部有一个缓存机制,使用了享元模式来共享一定范围内的 Integer 对象,以此减少对象的创建数量,节省内存。Integer.valueOf()
方法会优先从缓存中获取 Integer 对象,若缓存中不存在才会创建新对象。再例如,java.lang.String
类的字符串常量池是享元模式的典型应用。当创建字符串对象时,如果字符串常量池中已经存在相同内容的字符串,就会直接返回常量池中的对象,而不是创建新对象。
创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️