Java中的享元模式

2023/05/26

1. 概述

在本文中,我们介绍享元设计模式。此模式用于减少内存占用,它还可以提高对象实例化成本高昂的应用程序的性能。

简而言之,享元模式基于一个工厂,该工厂通过在创建后存储它们来回收创建的对象。每次请求一个对象时,工厂都会查找该对象以检查它是否已经创建。如果有,则返回现有对象;否则将创建一个新对象,存储然后返回。

享元对象的状态由一个与其他类似对象共享的不变组件(内在)和一个可以由客户端代码操作的变体组件(外在)组成。

享元对象的不可变性非常重要:对状态的任何操作都必须由工厂执行

2. 实现

该模式的主要元素是:

  • 定义客户端代码可以对享元对象执行的操作的接口
  • 我们接口的一个或多个具体实现
  • 处理对象实例化和缓存的工厂

接下来让我们看看如何实现每个组件。

2.1 Vehicle接口

首先,我们创建一个Vehicle接口。由于此接口将是工厂方法的返回类型,因此我们需要确保公开所有相关方法:

public void start();
public void stop();
public Color getColor();

2.2 具体的Vehicle实现

接下来,让我们将Car类作为具体的Vehicle。我们的Car将实现Vehicle接口的所有方法,至于它的状态,它将有一个engine和一个color字段:

private Engine engine;
private Color color;

2.3 Vehicle工厂

最后但同样重要的是,我们将创建VehicleFactory。制造一辆新车是一项非常昂贵的操作,因此工厂只会为每种颜色制造一辆汽车。

为此,我们使用Map作为简单缓存来跟踪创建的车辆:

private static Map<Color, Vehicle> vehiclesCache = new HashMap<>();

public static Vehicle createVehicle(Color color) {
    Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> { 
        Engine newEngine = new Engine();
        return new Car(newEngine, newColor);
    });
    return newVehicle;
}

请注意,客户端代码只能影响对象的外部状态(车辆的颜色),并将其作为参数传递给createVehicle方法。

3. 用例

3.1 数据压缩

享元模式的目标是通过共享尽可能多的数据来减少内存使用量,因此,它是无损压缩算法的良好基础。在这种情况下,每个享元对象都充当一个指针,其外部状态是上下文相关的信息。

这种用法的一个典型例子是在文字处理器中。在这里,每个角色都是一个享元对象,共享渲染所需的数据。因此,只有字符在文档中的位置会占用额外的内存。

3.2 数据缓存

许多现代应用程序使用缓存来缩短响应时间。享元模式类似于缓存的核心概念,可以很好地满足这个目的。

当然,此模式与典型的通用缓存在复杂性和实现方面存在一些关键差异。

4. 总结

总而言之,本快速教程重点介绍了Java中的享元设计模式,并介绍了一些涉及该模式的最常见场景。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章