享元模式详解--初听很抽象,实际是共享内存概念
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();
}
}