【Java】23种设计模式——11.享元模式
概念
享元模式(Flyweight Pattern) 是 GoF 23种设计模式 中的 结构型模式,核心思想是 通过共享技术高效支持大量细粒度对象的复用,减少内存消耗。适用于系统中存在大量相似对象且对象状态可分离的场景(如字符渲染、游戏粒子系统)。
享元模式的特点
- 内部状态vs外部状态 内部状态不可变(如颜色),由享元对象存储;外部状态可变(如位置),由客户端传递
- 对象复用 通过工厂缓存共享对象,避免重复创建
角色
| 角色 | 职责 |
|---|---|
| Flyweight(抽象化共享对象) | 定义共享对象的接口(如 Shape 接口) |
| ConcreteFlyweight(具体共享对象) | 实现具体共享对象(如 Circle 类),存储 内部状态(不可变部分) |
| FlyweightFactory(共享对象工厂) | 管理共享对象的工厂,确保对象复用(如缓存池) |
| Client(共享客户端) | 使用享元对象,维护 外部状态(可变部分) |
适用场景
系统中存在大量相似对象、对象的大部分状态可以外部化
- 文本编辑器 每个字符的字体、大小作为内部状态共享,位置、颜色作为外部状态传递。
- 游戏开发 例子系统(如子弹、火焰)复用相同的纹理和模型,仅位置、速度由外部控制。
- 数据连接池 复用已经建立的连接对象,避免频繁创建和销毁。
使用
-
抽象化共享对象(享元接口) (形状抽象化)
/** * 抽象化共享对象 : 形状 * @Author:lyj * @Date:2025/5/15 14:29 */ public interface Shap { /** * 绘制形状, x,y为外部状态(由客户端传递) * @param x * @param y */ public void draw(int x, int y); } -
具体共享对象(享元对象) (圆形、多边形)
/** * 具体享元类 : 圆(内部状态,颜色) * @Author:lyj * @Date:2025/5/15 14:32 */ public class Circle implements Shap { private String color; // 颜色 public Circle(String color) { this.color = color; } @Override public void draw(int x, int y) { System.out.printf("圆形{颜色:[%s],位置[%d,%d]} ",color ,x,y); System.out.println(); } }/** * 具体享元类 : 多边形(内部状态,边数量) * @Author:lyj * @Date:2025/5/15 14:32 */ public class Polygon implements Shap { private String color; // 颜色 public Polygon(String color) { this.color = color; } @Override public void draw(int x, int y) { System.out.printf("多边形{颜色[%s],位置[%d,%d]}",color ,x,y); System.out.println(); } } -
共享对象工厂(享元工厂) 获取图形形状、位置
/** * 享元工厂类 : 获取形状对象(颜色、位置) * @Author:lyj * @Date:2025/5/15 15:26 */ public class ShapFactory { private static final Map<String, Shap> shapes = new HashMap<>(); /** * 获取共享对象(按颜色复用) * @param type 类型 * @param color 颜色 * @return */ public static Shap getShape(String type, String color) { String key = type + color; Shap shape = shapes.get(key); if (shape == null){ switch (type.toLowerCase()){ case "圆形": shape = new Circle(color); break; case "多边形": shape = new Polygon(color); break; default: throw new IllegalArgumentException("不支持形状类型"); } shapes.put(key,shape); } return shape; } } -
共享客户端
运行结果,详见注释
// 外部状态(位置)由客户端维护 int[][] points = {{1,2}, {3,4}, {5,6},{7,8},{9,10},{11,12}}; // 通过工厂类获取享元对象 Shap redCircle = ShapFactory.getShape("圆形","红色"); Shap blueCircle = ShapFactory.getShape("圆形","蓝色"); Shap yellowCircle = ShapFactory.getShape("圆形","黄色"); Shap redPolygon = ShapFactory.getShape("多边形","红色"); Shap bluePolygon = ShapFactory.getShape("多边形","蓝色"); Shap yellowPolygon = ShapFactory.getShape("多边形","黄色"); // 绘制图形(传递外部形态) redCircle.draw(points[0][0],points[0][1]); //圆形{颜色:[红色],位置[1,2]} blueCircle.draw(points[1][0],points[1][1]); //圆形{颜色:[蓝色],位置[3,4]} yellowCircle.draw(points[2][0],points[2][1]); //圆形{颜色:[黄色],位置[5,6]} redPolygon.draw(points[3][0],points[3][1]); //多边形{颜色:[红色],位置[7,8]} bluePolygon.draw(points[4][0],points[4][1]); //多边形{颜色:[蓝色],位置[9,10]} yellowPolygon.draw(points[5][0],points[5][1]); //多边形{颜色:[黄色],位置[11,12]}
有志者,事竟成,破釜沉舟,百二秦关终属楚; 苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

浙公网安备 33010602011771号