Java设计模式 —— 享元模式
14 享元模式
14.1 享元模式概述
Flyweight Pattern: 运用共享技术有效地支持大量细粒度对象的复用。
当系统中存在大量相同或相似的对象时,它通过共享技术实现相同或相似的细粒度对象的复用,从而节约了内存空间,提高系统性能。在享元模式中提供了一个享元池用于存储已经创建好的享元对象,并通过享元工厂类将享元对象提供给客户端使用。
享元模式结构图如下所示:
14.2 享元模式实现
14.2.1 抽象享元接口
抽象享元类声明了享元类公共的方法,这些方法可以向外界提供享元对象的内部状态,同时也可以通过这些方法设置外部状态。
public interface Flyweight {
public void operation(String extrinsicState);
}
14.2.2 具体享元类
该类中需要将内部状态与外部状态分开处理,通常将内部状态作为成员变量,而外部状态通过注入的方式添加到类中。
public class ConcreteFlyweight implements Flyweight {
// 内部状态
private String intrinsicState;
public ConcreteFlyweight(String intrinsicState) {
this.intrinsicState = intrinsicState;
}
// 可以使用不同的外部状态注入 operation() 内
public void operation(String extrinsicState) {
// 业务逻辑代码
}
}
// 非共享具体享元类
public class UnsharedConcreteFlyweight implements Flyweight {
public void operation(String extrinsicState) {
// 业务逻辑代码
}
}
14.2.3 享元工厂类
该类提供一个存储享元对象的享元池,当用户获取对象时首先从享元池查找,若池内不存在,则创建一个新的享元对象返回,并将新对象添加到享元池内。
public class FlyweightFactory {
private static FlyweightFactory instance = new FlyweightFactory();
private Map<String, Flyweight> flyweights = new HashMap<>();
private FlyweightFactory() {}
public static FlyweightFactory getInstance() {
return instance;
}
public Flyweight getFlyweight(String key) {
if (flyweights.containsKey(key)) {
return flyweights.get(key);
}
else {
String intrinsicState = "intrinsic";
Flyweight flyweight = new ConcreteFlyweight(intrinsicState);
flyweights.put(intrinsicState, flyweight);
return flyweight;
}
}
}
14.2.4 客户端调用
public class Client {
public static void main(String[] args) {
FlyweightFactory factory = FlyweightFactory.getInstance();
String key = "a";
String extrinsicState = "b";
Flyweight flyweight = factory.getFlyweight(key);
// 结合外部状态调用 operation
flyweight.operation(extrinsicState);
}
}
14.3 享元模式的优/缺点
享元模式使用常见:Java String 类 (字符串常量池)
享元模式的优点主要如下:
- 减少内存中的重复对象的数量,节约系统资源
- 享元模式的外部状态相对独立,使得享元对象可以在不同环境中被共享
享元模式的缺点主要如下:
- 享元模式需要将类的内部状态与外部状态分离,使得内部状态可共享且执行业务时可能需要从读入外部状态,增加系统的复杂性