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 类 (字符串常量池)

享元模式的优点主要如下:

  • 减少内存中的重复对象的数量,节约系统资源
  • 享元模式的外部状态相对独立,使得享元对象可以在不同环境中被共享

享元模式的缺点主要如下:

  • 享元模式需要将类的内部状态与外部状态分离,使得内部状态可共享且执行业务时可能需要从读入外部状态,增加系统的复杂性
posted @ 2022-10-25 10:55  ylyzty  阅读(26)  评论(0编辑  收藏  举报