2

我觉得我对设计模式有一个很好的掌握,但是我似乎无法理解一件事,而且在我查看的资源中似乎也没有得到确切的解释。
那个问题是,考虑到对象是独立的实体,数据如何通用,而不是静态数据?

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 检索具有某种颜色的圆,但这会创建一个新的圆实例,没有持久引用圆的颜色。
因此,除非我弄错了,否则没有实际的共享数据,所以我不确定这会如何提供除了在创建期间之外的好处。

4

1 回答 1

2

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具有特定颜色的 a 已经存在,它将从circleMap.

这在文中也有解释:

ShapeFactory 有一个 Circle 的 HashMap,其键是 Circle 对象的颜色。每当有请求向 ShapeFactory 创建一个特定颜色的圆时,它会检查其 HashMap 中的圆对象,如果找到 Circle 的对象,则返回该对象,否则创建一个新对象,存储在 hashmap 中以供将来使用,并返回给客户。

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

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 的好处。享元的主要目的是将共享状态外部化。我知道的常见示例在文档中使用字符属性。

您可以将后三个外部化,而不是Character使用position,和,从而减少每个实例所需的内存:fontsizetextDecorationCharacter

这是一些文字。

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

这是一些粗体字。

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

于 2017-11-13T11:54:33.670 回答