结构型-享元模式
2026/1/15大约 2 分钟Java设计模式结构型模式享元模式Java设计模式面向对象架构设计最佳实践代码优化
概述
享元模式(Flyweight Pattern)运用共享技术有效地支持大量细粒度的对象。通过共享已经存在的对象来大幅度减少需要创建的对象数量。
适用场景
- 系统中有大量相似对象,造成内存大量耗费
- 对象的大部分状态都可以外部化
- 需要缓冲池的场景
角色组成
- Flyweight(抽象享元):定义对象的外部状态和内部状态的接口
- ConcreteFlyweight(具体享元):实现抽象享元角色
- UnsharedConcreteFlyweight(非共享具体享元):不能被共享的子类
- FlyweightFactory(享元工厂):创建并管理享元对象
内部状态与外部状态
- 内部状态:存储在享元对象内部,不会随环境改变而改变,可以共享
- 外部状态:随环境改变而改变,不可以共享,由客户端保存
代码实现
1. 抽象享元
public interface ChessPiece {
void display(int x, int y); // x, y 是外部状态
}2. 具体享元
public class ConcreteChessPiece implements ChessPiece {
private String color; // 内部状态
public ConcreteChessPiece(String color) {
this.color = color;
}
@Override
public void display(int x, int y) {
System.out.println(color + "棋子,位置: (" + x + ", " + y + ")");
}
}3. 享元工厂
public class ChessPieceFactory {
private static Map<String, ChessPiece> pieces = new HashMap<>();
public static ChessPiece getChessPiece(String color) {
ChessPiece piece = pieces.get(color);
if (piece == null) {
piece = new ConcreteChessPiece(color);
pieces.put(color, piece);
System.out.println("创建" + color + "棋子");
}
return piece;
}
public static int getCount() {
return pieces.size();
}
}4. 客户端
public class Client {
public static void main(String[] args) {
// 创建棋子
ChessPiece black1 = ChessPieceFactory.getChessPiece("黑");
black1.display(1, 1);
ChessPiece black2 = ChessPieceFactory.getChessPiece("黑");
black2.display(2, 2);
ChessPiece white1 = ChessPieceFactory.getChessPiece("白");
white1.display(3, 3);
System.out.println("棋子对象数量: " + ChessPieceFactory.getCount());
System.out.println("black1 == black2: " + (black1 == black2));
}
}# 输出
创建黑棋子
黑棋子,位置: (1, 1)
黑棋子,位置: (2, 2)
创建白棋子
白棋子,位置: (3, 3)
棋子对象数量: 2
black1 == black2: true类图
JDK 中的应用
Integer 缓存池
Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b); // true(-128~127 缓存)
Integer c = Integer.valueOf(200);
Integer d = Integer.valueOf(200);
System.out.println(c == d); // falseString 常量池
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true(字符串常量池)
String s3 = new String("hello");
System.out.println(s1 == s3); // false
System.out.println(s1 == s3.intern()); // true优缺点
优点:
- 大大减少对象的创建,降低系统内存
- 减少内存之外的其他资源占用
缺点:
- 需要分离出内部状态和外部状态
- 使系统逻辑复杂化
享元模式 vs 单例模式
| 特性 | 享元模式 | 单例模式 |
|---|---|---|
| 对象数量 | 多个(按类型) | 1个 |
| 关注点 | 共享对象 | 唯一实例 |
| 状态 | 区分内外部状态 | 无此概念 |
