享元设计模式

2025年3月17日 | 阅读 7 分钟

与外观、适配器和装饰器模式一样,享元设计模式是一种结构型模式。当需要创建大量类对象时,就会应用享元设计模式。通过共享对象,享元设计模式有助于减轻内存压力,这对于嵌入式系统和移动设备等内存有限的设备至关重要。这是因为每个对象都会占用内存空间。在使用享元设计模式之前,必须考虑以下要素:

  • 程序应该生成大量对象。
  • 创建对象的过程会占用大量内存,并且可能需要一些时间。
  • 项的外部属性应由客户端程序确定。对象的属性可分为内部属性和外部属性。

为了应用享元模式,我们必须将对象属性分为内部属性和外部属性。外部属性由客户端代码设置并用于各种目的,而内部属性则赋予对象独特的特性。例如,一个 Circle 对象可能具有颜色和粗细等外部属性。为了应用享元模式,我们必须构建一个享元工厂来生成共享对象。让我们举一个需要使用线和椭圆绘制某些东西的例子。因此,我们将拥有一个 Shape 接口及其具体实现,即 Line 和 Oval。Line 没有内部属性,而 oval 类将有一个来决定是否用指定的颜色填充椭圆。

Line.java

Oval.java

享元工厂

我们需要在享元工厂中维护一个对象映射,客户端应用程序不应该能够访问它,因为享元工厂将由客户端程序用于实例化对象。当客户端程序调用 HashMap 以检索对象实例时,应该始终返回该对象;如果找不到,则应该创建一个新对象,将其添加到 Map 中,然后返回。在生成对象时,我们必须确保考虑所有内部属性。以下是我们享元工厂类的代码。

请注意 getShape 函数如何使用工厂设计模式、Java 组合(形状映射)和 Java 枚举来实现类型安全。

享元设计模式客户端示例

下面展示了一个使用享元模式实现的示例程序。Java DrawingClient。

DrawingClient.java

输出

Creating Line object
Creating Oval object with fill=true
Creating Oval object with fill=false

我使用随机数生成器为我们的框架创建了多种形状。如果您执行上面的客户端程序,您可能会注意到创建第一个 Line 对象以及填充为 true 和 false 的 Oval 对象存在延迟。之后,因为使用的是共享对象,所以程序运行速度很快。多次点击“绘制”按钮后,框架应类似于下图。

Flyweight Design Pattern

到此为止,我们讨论了享元模式;在接下来的文章中,我们将研究其他设计模式。如果您喜欢,请在评论区告诉我们,并广为传播。

输出

Counter Terrorist Created 
Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB 
Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB 
Terrorist Created 
Terrorist with weapon AK-47| Task is PLANT A BOMB 
Terrorist with weapon Gut Knife| Task is PLANT A BOMB 
Terrorist with weapon Gut Knife| Task is PLANT A BOMB 
Terrorist with weapon Desert Eagle| Task is PLANT A BOMB 
Terrorist with weapon AK-47| Task is PLANT A BOMB 
Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB 
Counter Terrorist with weapon Gut Knife| Task is DIFFUSE BOMB 
Counter Terrorist with weapon Desert Eagle| Task is DIFFUSE BOMB