前言
- 掌握享元模式的应用场景
- 了解享元模式的内部状态和外部状态
一、定义
享元模式(Flyweight Pattern):运用共享技术来有效地支持大量细粒度对象的复用。
它通过共享已经存在的对象来减少需要创建的对象数量,从而提高系统资源的利用率。
享元模式的本质是缓存共享对象,降低内存消耗。
二、应用场景
- 系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源。
- 大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态。
- 由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有足够多的享元实例时才使用享元对象。
三、基本结构
- 抽象享元角色(Flyweight): 是所有的具体享元类的基类,为具体享元规范需要实现的公共接口,非享元的外部状态以参数的形式通过方法传入。
- 具体享元角色(Concrete Flyweight):实现抽象享元角色中所规定的接口。
- 享元工厂角色(Flyweight Factory):负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检查系统中是否存在符合要的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。
- 客户端角色(Client):调用享元工厂,并从中获取具体的享元对象。
四、基本使用
1. 抽象享元角色
public interface Flyweight {
void operate();
}
2. 具体享元角色
public class ConcreteFlyweight implements Flyweight {
private String key;
public ConcreteFlyweight(String key) {
this.key = key;
System.out.println("具体的享元" + key + "被创建");
}
@Override
public void operate() {
System.out.println("具体的享元" + key + "被调用");
}
}
3. 享元工厂角色
public class FlyweightFactory {
private Map<String, Flyweight> flyweightMap = new HashMap<>();
public Flyweight getFlyweight(String key) {
Flyweight flyweight = flyweightMap.get(key);
if (flyweight == null) {
flyweight = new ConcreteFlyweight(key);
flyweightMap.put(key, flyweight);
}
return flyweight;
}
}
4. 客户端
public class Client {
public static void main(String[] args) {
FlyweightFactory factory = new FlyweightFactory();
factory.getFlyweight("1").operate();
factory.getFlyweight("2").operate();
factory.getFlyweight("2").operate();
}
}
总结
1. 优点
- 相同对象只要保存一份,着降低了系统中对象的数量,从而降低了系统中细粒度对象给内从带来的压力。
2. 缺点
- 为了使对象可以共享,需要将一些不能共享的状态外部化,这将增加程序的复杂性。
- 读取享元模式的外部状态会使得运行时间稍微变长。