介绍Java享元模式(Flyweight)
本文我们探讨一种结构模式————享元模式。一般用于减少内存占用,对于对象实例化比较昂贵的应用可以提升应用的性能。
简言之,享元模式基于工厂重用已创建的对象。每次调用对象时,工厂检查对象是否已经创建。如果是,则返回已存在对象,否则创建新的对象,存储并返回。
共享对象的状态由一个不变组件(内部的)和一个可以由客户端代码操作的变量组件(外部的)组成。共享对象时不变的这点很重要:对其状态的任何操作都必须有工厂执行。
示例实现
享元模式主要元素包括:
- 定义客户端代码能在享元对象上执行操作的接口
- 一个或多个接口实现
- 一个工厂负责对象实例化及缓存
下面我们实现每个组件。
Vehicle 接口
我们首先定义Vehicle 接口。由于这个接口将是工厂方法的返回类型,我们需要确保公开所有相关的方法:
public void start();
public void stop();
public Color getColor();
Vehicle接口实现
接下来,我们定义Car类实现Vehicle接口,并实现其所有方法。该对象的状态有两个engine和color字段:
import java.awt.Color;
import javax.annotation.concurrent.Immutable;
/**
* Represents a car. This class is immutable.
*/
@Immutable
@Slf4j
public class Car implements Vehicle {
private Engine engine;
private Color color;
/**
* Instantiates a new Car.
*/
public Car(Engine engine, Color color) {
this.engine = engine;
this.color = color;
// Building a new car is a very expensive operation!
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
LOG.error("Error while creating a new car", e);
}
}
@Override
public void start() {
LOG.info("Car is starting!");
engine.start();
}
@Override
public void stop() {
LOG.info("Car is stopping!");
engine.stop();
}
@Override
public Color getColor() {
return this.color;
}
}
Vehicle 工厂
最后但并非最不重要的,我们将创建VehicleFactory。制造一辆新车是一个非常昂贵的操作,所以工厂将针对每种颜色仅生产一辆。因此我们使用map作为缓存保存已创建的对象:
import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
public class VehicleFactory {
/**
* Stores the already created vehicles.
*/
private static Map<Color, Vehicle> vehiclesCache = new HashMap<Color, Vehicle>();
/**
* Private constructor to prevent this class instantiation.
*/
private VehicleFactory() {
}
/**
* Returns a vehicle of the same color passed as argument. If that vehicle
* was already created by this factory, that vehicle is returned, otherwise
* a new one is created and returned.
*/
public static Vehicle createVehicle(Color color) {
// Looks for the requested vehicle into the cache.
// If the vehicle doesn't exist, a new one is created.
Vehicle newVehicle = vehiclesCache.computeIfAbsent(color, newColor -> {
// Creates the new car.
Engine newEngine = new Engine();
return new Car(newEngine, newColor);
});
return newVehicle;
}
}
注意客户端代码仅能通过传入参数影响对象的外部状态(即color)。
很多应用使用缓存提升响应速度。享元模式与缓存的核心概念类似,能够很好地实现该目的。当然,在复杂性和实现方面,此模式与典型的通用缓存有几个关键区别。
总结
本快速教程主要关注Java中的享元(flyweight)设计模式。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/89814765