什么是享元模式?享元模式案例教程

什么是享元模式?享元模式案例教程
最新回答
我历史不好别跟我提以往

2026-04-24 09:33:35

享元模式是一种结构型设计模式,通过共享技术复用大量细粒度对象,减少内存占用并提高性能。 其核心在于区分对象的内部状态(可共享)和外部状态(不可共享),并通过工厂管理共享对象。

享元模式的核心角色
  1. 抽象享元角色(Flyweight)

    定义共享对象的公共接口(如AbstractBox),声明内部状态和外部状态的操作方法。

  2. 具体享元角色(Concrete Flyweight)

    实现抽象接口,存储内部状态(如IBox、LBox等具体形状类)。

  3. 非享元角色(Unsharable Flyweight)

    不需要共享的子类(案例中未涉及,但可用于扩展非共享属性)。

  4. 享元工厂(Flyweight Factory)

    管理享元对象池(如BoxFactory),通过单例模式确保唯一性,按需提供共享对象。

俄罗斯方块案例解析问题背景
  • 每个俄罗斯方块有形状(内部状态)和颜色(外部状态)。
  • 若为每种形状和颜色组合创建独立对象,会导致内存浪费(如7种形状×10种颜色=70个对象)。
优化方案
  • 内部状态:方块形状(I、L、O等),通过具体享元类实现并共享。
  • 外部状态:颜色(红、蓝等),由客户端动态传入,不存储在享元对象中。
代码实现
  1. 抽象享元类定义共性行为(如显示形状和颜色):

    public abstract class AbstractBox { public abstract String getShape(); public void display(String color) { System.out.println("方块形状:" + getShape() + " 颜色:" + color); }}
  2. 具体享元类实现不同形状(I、L、O):

    public class IBox extends AbstractBox { @Override public String getShape() { return "I"; }}public class LBox extends AbstractBox { @Override public String getShape() { return "L"; }}
  3. 享元工厂使用单例模式管理对象池,避免重复创建:

    public class BoxFactory { private static HashMap<String, AbstractBox> map; private BoxFactory() { map = new HashMap<>(); map.put("I", new IBox()); map.put("L", new LBox()); map.put("O", new OBox()); } public static BoxFactory getInstance() { return SingletonHolder.INSTANCE; } private static class SingletonHolder { private static final BoxFactory INSTANCE = new BoxFactory(); } public AbstractBox getBox(String key) { return map.get(key); }}
  4. 客户端调用通过工厂获取共享对象,并动态设置颜色(外部状态):

    public class Client { public static void main(String[] args) { BoxFactory factory = BoxFactory.getInstance(); AbstractBox box1 = factory.getBox("I"); box1.display("红色"); // 输出:方块形状:I 颜色:红色 AbstractBox box2 = factory.getBox("L"); box2.display("蓝色"); // 输出:方块形状:L 颜色:蓝色 }}
享元模式的优势
  1. 减少内存占用

    仅存储内部状态的对象(如7种形状)被复用,而非为每种颜色创建新对象。

  2. 提升性能

    避免频繁创建和销毁相似对象,适合游戏、文本编辑器等场景。

  3. 分离变与不变

    内部状态(不变)与外部状态(可变)解耦,增强灵活性。

适用场景
  • 系统存在大量相似对象(如棋盘中的棋子、图形编辑器中的符号)。
  • 对象内部状态可共享,外部状态可通过参数动态传入。
  • 需要频繁创建/销毁对象的场景(如游戏开发、缓存管理)。
总结

享元模式通过共享对象池优化内存使用,尤其适合细粒度对象的复用。在俄罗斯方块案例中,形状作为内部状态被共享,颜色作为外部状态动态传递,显著减少了对象数量。理解内部/外部状态的区分是应用享元模式的关键。