java的享元模式

发布于:2025-03-21 ⋅ 阅读:(32) ⋅ 点赞:(0)
1. 什么是享元模式?

享元模式(Flyweight Pattern)是一种结构型设计模式,通过共享对象来减少内存占用,从而高效支持大量细粒度的对象。其核心思想是分离对象的内部状态(可共享)和外部状态(不可共享),通过共享内部状态来避免重复创建对象。


2. 核心概念
  • 内部状态:对象中不变的部分,可以被多个对象共享(例如:颜色、字体)。

  • 外部状态:对象中变化的部分,由客户端传入(例如:位置、尺寸)。


3. 模式结构
  • Flyweight:定义享元对象的接口(例如:Shape)。

  • ConcreteFlyweight:实现享元接口,保存内部状态(例如:ColorShape)。

  • FlyweightFactory:创建并管理享元对象池,确保共享(例如:ShapeFactory)。


4. 实现示例:图形绘制系统

假设需要绘制大量不同颜色的圆形,颜色是内部状态,坐标是外部状态。

步骤 1:定义享元接口
public interface Shape {
    void draw(int x, int y);  // 外部状态由参数传入
}
步骤 2:实现具体享元类
public class ColorShape implements Shape {
    private final String color;  // 内部状态(不可变)

    public ColorShape(String color) {
        this.color = color;
    }

    @Override
    public void draw(int x, int y) {
        System.out.println(
            "Drawing " + color + " circle at (" + x + ", " + y + ")"
        );
    }
}
步骤 3:创建享元工厂
import java.util.HashMap;
import java.util.Map;

public class ShapeFactory {
    private static final Map<String, Shape> shapes = new HashMap<>();

    public static Shape getShape(String color) {
        // 如果颜色不存在,则创建新对象并缓存
        Shape shape = shapes.computeIfAbsent(color, ColorShape::new);
        return shape;
    }
}
步骤 4:客户端使用
public class Client {
    public static void main(String[] args) {
        // 获取红色圆形(首次创建)
        Shape redCircle = ShapeFactory.getShape("red");
        redCircle.draw(10, 20);  // 传入外部状态坐标

        // 再次获取红色圆形(共享已有对象)
        Shape sameRedCircle = ShapeFactory.getShape("red");
        sameRedCircle.draw(30, 40);

        // 验证是否为同一对象
        System.out.println("Same instance? " + (redCircle == sameRedCircle));

        // 获取蓝色圆形(创建新对象)
        Shape blueCircle = ShapeFactory.getShape("blue");
        blueCircle.draw(50, 60);
    }
}
输出结果
Drawing red circle at (10, 20)
Drawing red circle at (30, 40)
Same instance? true
Drawing blue circle at (50, 60)

5. 享元模式在 JDK 中的应用
  • Integer.valueOf(int):缓存了 -128 到 127 的整数对象。

  • String 常量池:相同字符串字面量指向同一内存。


6. 适用场景
  • 系统中存在大量相似对象。

  • 对象的大部分状态可以外部化。

  • 需要减少内存消耗或对象创建开销。


7. 优缺点
  • 优点

    • 大幅减少内存占用。

    • 提高性能(减少对象创建和垃圾回收)。

  • 缺点

    • 增加系统复杂度(需分离内外状态)。

    • 线程安全问题需额外处理(共享对象可能被多线程修改)。


8. 扩展思考
  • 外部状态管理:通常由客户端维护外部状态,享元对象仅处理内部状态。

  • 复合享元:将多个享元组合成树形结构,支持更复杂的共享逻辑。

通过合理使用享元模式,可以在处理大量细粒度对象时显著优化资源利用。


网站公告

今日签到

点亮在社区的每一天
去签到