设计模式-享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,用于高效共享大量细粒度对象,从而减少内存消耗。它通过分离对象的状态为内部状态(Intrinsic)和外部状态(Extrinsic),使得多个对象可以共享相同的内部状态,而外部状态则在使用时动态传入。// 棋子接口项目描述内部状态color 字段:所有相同颜色的棋子共享该实例。外部状态Position 对象:每次调用 display
·
1. 什么是享元模式?
享元模式(Flyweight Pattern) 是一种结构型设计模式,用于高效共享大量细粒度对象,从而减少内存消耗。它通过分离对象的状态为内部状态(Intrinsic)和外部状态(Extrinsic),使得多个对象可以共享相同的内部状态,而外部状态则在使用时动态传入。
2. 核心思想
- 内部状态(Intrinsic State):对象的共享部分,不会随环境变化,可以在多个上下文中重复使用。
- 外部状态(Extrinsic State):对象的非共享部分,依赖于具体使用场景,由外部传入。
3. 适用场景
- 系统中存在大量相似对象,且这些对象的状态可以分解为内部和外部状态。
- 对象的创建和销毁成本较高,而共享对象能显著降低资源消耗。
- 典型场景:文本编辑器中的字符、游戏中的角色、图形绘制中的颜色对象等。
Java 实现样例
示例:棋子共享工厂
假设我们要设计一个国际象棋游戏,棋子(如“白棋”和“黑棋”)的颜色是内部状态,而位置是外部状态。通过享元模式,我们可以复用相同颜色的棋子对象。
1. 定义享元接口(Flyweight)
// 棋子接口
public interface ChessPiece {
void display(Position position);
}
2. 具体享元类(ConcreteFlyweight)
// 棋子具体实现类
public class ChessPieceImpl implements ChessPiece {
// 内部状态:颜色(共享)
private final String color;
public ChessPieceImpl(String color) {
this.color = color;
System.out.println("创建棋子: " + color);
}
@Override
public void display(Position position) {
System.out.println("棋子颜色: " + color + ", 位置: (" + position.getX() + ", " + position.getY() + ")");
}
}
3. 外部状态类(Extrinsic State)
// 棋子位置(外部状态)
public class Position {
private final int x;
private final int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
4. 享元工厂(FlyweightFactory)
// 棋子工厂:管理共享对象
public class ChessPieceFactory {
// 使用 HashMap 缓存已创建的棋子
private static final Map<String, ChessPiece> POOL = new HashMap<>();
public static ChessPiece getChessPiece(String color) {
ChessPiece piece = POOL.get(color);
if (piece == null) {
piece = new ChessPieceImpl(color);
POOL.put(color, piece);
}
return piece;
}
public static int getCreatedCount() {
return POOL.size();
}
}
5. 客户端代码(Client)
public class Client {
public static void main(String[] args) {
// 创建多个棋子
ChessPiece white1 = ChessPieceFactory.getChessPiece("White");
ChessPiece white2 = ChessPieceFactory.getChessPiece("White");
ChessPiece black = ChessPieceFactory.getChessPiece("Black");
// 验证共享:white1 和 white2 是同一个对象
System.out.println("white1 == white2? " + (white1 == white2)); // 输出 true
// 显示不同位置的棋子
white1.display(new Position(1, 2));
black.display(new Position(3, 4));
white2.display(new Position(5, 6));
}
}
6. 输出结果
创建棋子: White
创建棋子: Black
white1 == white2? true
棋子颜色: White, 位置: (1, 2)
棋子颜色: Black, 位置: (3, 4)
棋子颜色: White, 位置: (5, 6)
关键点总结
| 项目 | 描述 |
|---|---|
| 内部状态 | color 字段:所有相同颜色的棋子共享该实例。 |
| 外部状态 | Position 对象:每次调用 display() 时动态传入。 |
| 工厂作用 | 控制对象创建,确保相同颜色的棋子只创建一次。 |
| 优点 | 节省内存,避免重复创建对象;提高性能。 |
| 缺点 | 增加系统复杂度;需要区分内外状态,维护成本较高。 |
| 适用场景 | 大量细粒度对象存在相似性,且对象创建成本较高时。 |
应用扩展
- 文本编辑器:字符对象(如
Character)可共享,字体、颜色等作为外部状态。 - 游戏开发:子弹、敌人等对象可通过享元模式减少内存占用。
- Web 服务:共享连接池中的数据库连接对象。
通过合理使用享元模式,可以在保证系统性能的同时,降低资源消耗。
更多推荐

所有评论(0)