享元模式详解--初听很抽象,实际是共享内存概念

时间:2025-04-09 07:19:01
import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; // ================== 享元对象 ================== /** * 树木固有属性(享元内部状态) */ class TreeType { private final String species; // 树种 private final String texture; // 纹理路径 private final byte[] modelData;// 模型数据(模拟大对象) public TreeType(String species, String texture) { this.species = species; this.texture = texture; // 模拟加载大模型数据(实际应从文件读取) this.modelData = new byte[1024 * 1024]; // 1MB System.out.println("加载树种:" + species); } public void render(int x, int y) { System.out.printf("渲染%s树@(%d,%d) 使用纹理:%s\n", species, x, y, texture); } } // ================== 享元工厂 ================== /** * 树木类型工厂(管理享元对象池) */ class TreeTypeFactory { private static final Map<String, TreeType> pool = new HashMap<>(); // 获取享元对象(线程安全) public static synchronized TreeType getTreeType(String species, String texture) { String key = species + "_" + texture; return pool.computeIfAbsent(key, k -> new TreeType(species, texture)); } // 统计当前共享类型数量(调试用) public static int getPoolSize() { return pool.size(); } } // ================== 上下文对象 ================== /** * 树木实例(包含外部状态) */ class Tree { private final TreeType type; // 共享的内部状态 private int x, y; // 外部状态 private int health; // 外部状态 public Tree(String species, String texture, int x, int y) { this.type = TreeTypeFactory.getTreeType(species, texture); this.x = x; this.y = y; this.health = 100; } public void render() { type.render(x, y); } // 更新外部状态 public void updatePosition(int newX, int newY) { this.x = newX; this.y = newY; } } // ================== 森林管理系统 ================== /** * 森林容器(管理百万级树木) */ class Forest { private static final int MAP_SIZE = 10000; private final Tree[] trees; public Forest(int treeCount) { trees = new Tree[treeCount]; initForest(); } private void initForest() { String[] species = {"橡树", "松树", "白桦"}; String[] textures = {"default", "autumn", "snow"}; for (int i = 0; i < trees.length; i++) { // 随机生成树种和坐标 String type = species[ThreadLocalRandom.current().nextInt(species.length)]; String texture = textures[ThreadLocalRandom.current().nextInt(textures.length)]; int x = ThreadLocalRandom.current().nextInt(MAP_SIZE); int y = ThreadLocalRandom.current().nextInt(MAP_SIZE); trees[i] = new Tree(type, texture, x, y); } } public void renderForest() { for (Tree tree : trees) { tree.render(); } } } // ================== 客户端代码 ================== public class FlyweightPatternDemo { public static void main(String[] args) { // 模拟渲染包含100万棵树的森林 Forest forest = new Forest(1000000); // 查看内存优化效果 System.out.println("\n实际创建的树种类型数量:" + TreeTypeFactory.getPoolSize()); System.out.println("理论内存节省:"); System.out.println(" - 未优化方案:" + (1_000_000 * 1024) + "KB"); System.out.println(" - 享元方案:" + (TreeTypeFactory.getPoolSize() * 1024) + "KB"); // 模拟渲染(实际应分批处理) forest.renderForest(); } }