全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-11 6 分钟 ✍️ juanwangdev

Java享元模式

享元模式通过共享对象减少内存消耗,适用于大量相似对象。

模式定义

意图:运用共享技术有效支持大量细粒度对象。

核心概念

内部状态

可共享的状态,存储在享元对象内部,不随环境改变。

外部状态

不可共享的状态,由客户端保存,使用时传入享元对象。

模式结构

享元接口

Java
public interface Flyweight {
    void operation(String externalState);
}

具体享元

Java
public class ConcreteFlyweight implements Flyweight {
    private String internalState;  // 内部状态

    public ConcreteFlyweight(String internalState) {
        this.internalState = internalState;
    }

    @Override
    public void operation(String externalState) {
        System.out.println("内部状态: " + internalState +
                          ", 外部状态: " + externalState);
    }
}

享元工厂

Java
public class FlyweightFactory {
    private Map<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        Flyweight flyweight = flyweights.get(key);
        if (flyweight == null) {
            flyweight = new ConcreteFlyweight(key);
            flyweights.put(key, flyweight);
            System.out.println("创建新享元: " + key);
        }
        return flyweight;
    }

    public int getFlyweightCount() {
        return flyweights.size();
    }
}

使用示例

Java
FlyweightFactory factory = new FlyweightFactory();

// 共享相同内部状态的享元
Flyweight f1 = factory.getFlyweight("A");  // 创建
Flyweight f2 = factory.getFlyweight("A");  // 复用
Flyweight f3 = factory.getFlyweight("B");  // 创建

f1.operation("状态1");
f2.operation("状态2");
f3.operation("状态3");

System.out.println("享元数量: " + factory.getFlyweightCount());  // 2

实际应用示例

棋子对象

Java
public interface ChessPiece {
    void display(int x, int y);
}

public class ConcreteChess implements ChessPiece {
    private String color;  // 内部状态(共享)
    private String type;   // 内部状态(共享)

    public ConcreteChess(String color, String type) {
        this.color = color;
        this.type = type;
    }

    @Override
    public void display(int x, int y) {  // x、y是外部状态
        System.out.println(color + " " + type + " 在位置(" + x + "," + y + ")");
    }
}

public class ChessFactory {
    private Map<String, ChessPiece> pieces = new HashMap<>();

    public ChessPiece getChess(String color, String type) {
        String key = color + "_" + type;
        ChessPiece piece = pieces.get(key);
        if (piece == null) {
            piece = new ConcreteChess(color, type);
            pieces.put(key, piece);
        }
        return piece;
    }
}

// 使用
ChessFactory factory = new ChessFactory();
ChessPiece blackKing = factory.getChess("黑", "将");
ChessPiece redKing = factory.getChess("红", "将");

// 同颜色同类型的棋子共享,位置不同
blackKing.display(1, 1);
blackKing.display(2, 3);  // 同一个对象,不同位置

Java中的享元

Integer缓存

Java
Integer a = Integer.valueOf(127);
Integer b = Integer.valueOf(127);
System.out.println(a == b);  // true,-128到127被缓存

Integer c = Integer.valueOf(128);
Integer d = Integer.valueOf(128);
System.out.println(c == d);  // false,超出缓存范围

String常量池

Java
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2);  // true,字符串常量池共享

享元模式优点

  1. 减少对象数量,节省内存
  2. 减少创建开销,提高性能
  3. 外部状态独立,不影响内部

享元模式缺点

  1. 分离内外状态增加复杂度
  2. 需维护享元工厂
  3. 状态变化可能影响共享逻辑

适用场景

  1. 大量相似对象
  2. 对象大部分状态可共享
  3. 内存受限场景
  4. 对象创建开销大

注意事项

内部状态必须不可变

外部状态由客户端管理

线程安全需考虑享元工厂

Java内置Integer、String常量池是享元应用

要点总结

  1. 享元模式共享内部状态,减少对象数量
  2. 内部状态共享存储,外部状态客户端保存
  3. 享元工厂管理享元对象池
  4. Java Integer缓存(-128~127)和String常量池是典型应用
  5. 适用于大量相似对象的内存优化场景

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java中介者模式
下一篇 → Java代理模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库