Java 中的享元模式在内存管理方面是如何工作的?

How does the Flyweight pattern in Java work with respect to memory management?

我觉得我对设计模式的把握还不错,但是我似乎无法理解一件事,而且我看过的资源中似乎也没有对它进行准确的解释。
这个问题是,如果数据不是静态的,考虑到对象是独立的实体,数据如何通用?

https://www.tutorialspoint.com/design_pattern/flyweight_pattern.htm

在这个例子中,我无法弄清楚优化发生在哪里,因为看起来好像每次都正常创建对象。

Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor());
circle.setX(getRandomX());
circle.setY(getRandomY());
circle.setRadius(100);
circle.draw();

这个代码块似乎是我最好的猜测,因为第一行从 HashMap 中检索了一个具有特定颜色的圆,但这创建了一个新的圆实例,没有持久引用圆的颜色。
因此,除非我弄错了,否则没有实际的共享数据,所以我不确定这除了可能在创建期间之外如何提供好处。

链接示例中的 ShapeFactory 将为每种颜色创建一个 Circle

import java.util.HashMap;

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

   public static Shape getCircle(String color) {
      Circle circle = (Circle)circleMap.get(color);

      if(circle == null) {
         circle = new Circle(color);
         circleMap.put(color, circle);
         System.out.println("Creating circle of color : " + color);
      }
      return circle;
   }
}

如果不存在具有指定颜色的 Circle,它将创建一个新的 Circle 对象并将该实例存储在 circleMap 哈希图中。如果具有特定颜色的 Circle 已经存在,它将 return 来自 circleMap.

的已经存在的实例

这个在文中也有说明:

ShapeFactory has a HashMap of Circle having key as color of the Circle object. Whenever a request comes to create a circle of particular color to ShapeFactory, it checks the circle object in its HashMap, if object of Circle found, that object is returned otherwise a new object is created, stored in hashmap for future use, and returned to client.

这在教程中显示的输出中也很明显:

Creating circle of color : Black
Circle: Draw() [Color : Black, x : 36, y :71, radius :100
Creating circle of color : Green
Circle: Draw() [Color : Green, x : 27, y :27, radius :100
Creating circle of color : White
Circle: Draw() [Color : White, x : 64, y :10, radius :100
Creating circle of color : Red
Circle: Draw() [Color : Red, x : 15, y :44, radius :100
Circle: Draw() [Color : Green, x : 19, y :10, radius :100
Circle: Draw() [Color : Green, x : 94, y :32, radius :100
Circle: Draw() [Color : White, x : 69, y :98, radius :100

每个颜色Circle只创建一次,但修改了很多次。


我同意教程并没有真正展示享元的好处。 flyweight 的要点是外部化共享状态。我知道的常见示例使用文档中的字符属性。

与其让一个 CharacterpositionfontsizetextDecoration,不如将后三个外部化,从而减少内存每个 Character 个实例需要:

This is some text.

在上面的行中,单个字符只需要存储它们的位置,但格式相同,因此可以外部化为单个享元对象。

This is some bold text.

在上面的行中,您有两个享元。一个用于常规文本,另一个用于四个粗体字符实例。