当前位置: 首页 > news >正文

设计模式-享源模式 - MaC

什么是享元模式?

享元模式是一种结构型设计模式,它通过共享技术来有效地支持大量细粒度的对象。享元模式通过共享已经存在的对象来减少创建对象的数量,从而减少内存占用和提高性能。
享元模式包含以下角色:

  • 享元接口(Flyweight):声明一个接口,通过它可以接受并作用于外部状态
  • 具体享元类(ConcreteFlyweight):实现享元接口,并为内部状态增加存储空间
  • 非共享具体享元类(UnsharedConcreteFlyweight):不需要共享的Flyweight子类
  • 享元工厂(FlyweightFactory):创建并管理flyweight对象,确保合理地共享flyweight

享元模式的优缺点

优点:

  • 减少内存使用:通过共享对象,大量减少对象的创建,节省内存空间
  • 提高性能:减少对象创建和垃圾回收的开销
  • 系统资源优化:有效利用系统资源,提高系统整体性能
    缺点:
  • 增加复杂性:需要区分内部状态和外部状态,增加了系统复杂性
  • 线程安全问题:共享对象可能带来线程安全问题,需要额外处理
  • 状态管理复杂:需要仔细管理对象的内部状态和外部状态

什么场景下使用享元模式

  1. 系统中有大量相似对象
  2. 这些对象的大部分状态都可以外部化
  3. 按照内部状态分成很多组,当把对象作为组来处理时,同一组的对象可以被共享
  4. 需要缓冲池的场景
  5. 对象创建开销大,但可以共享的场景

代码举例

// 享元接口 - 地形类型
interface Terrain {void render(int x, int y, String instanceData);boolean isWalkable();int getMovementCost();
}// 具体享元类 - 草地地形(内部状态:类型属性)
class GrassTerrain implements Terrain {private static final String TYPE = "Grass";private static final boolean WALKABLE = true;private static final int MOVEMENT_COST = 1;@Overridepublic void render(int x, int y, String instanceData) {System.out.printf("渲染草地地形在(%d,%d),实例数据:%s%n", x, y, instanceData);}@Overridepublic boolean isWalkable() {return WALKABLE;}@Overridepublic int getMovementCost() {return MOVEMENT_COST;}
}// 具体享元类 - 水域地形
class WaterTerrain implements Terrain {private static final String TYPE = "Water";private static final boolean WALKABLE = false;private static final int MOVEMENT_COST = Integer.MAX_VALUE;@Overridepublic void render(int x, int y, String instanceData) {System.out.printf("渲染水域地形在(%d,%d),实例数据:%s%n", x, y, instanceData);}@Overridepublic boolean isWalkable() {return WALKABLE;}@Overridepublic int getMovementCost() {return MOVEMENT_COST;}
}// 具体享元类 - 山地形
class MountainTerrain implements Terrain {private static final String TYPE = "Mountain";private static final boolean WALKABLE = false;private static final int MOVEMENT_COST = Integer.MAX_VALUE;@Overridepublic void render(int x, int y, String instanceData) {System.out.printf("渲染山地形在(%d,%d),实例数据:%s%n", x, y, instanceData);}@Overridepublic boolean isWalkable() {return WALKABLE;}@Overridepublic int getMovementCost() {return MOVEMENT_COST;}
}// 具体享元类 - 道路地形
class RoadTerrain implements Terrain {private static final String TYPE = "Road";private static final boolean WALKABLE = true;private static final int MOVEMENT_COST = 1;@Overridepublic void render(int x, int y, String instanceData) {System.out.printf("渲染道路地形在(%d,%d),实例数据:%s%n", x, y, instanceData);}@Overridepublic boolean isWalkable() {return WALKABLE;}@Overridepublic int getMovementCost() {return MOVEMENT_COST;}
}// 享元工厂
class TerrainFactory {private static final Map<String, Terrain> terrainTypes = new HashMap<>();static {terrainTypes.put("grass", new GrassTerrain());terrainTypes.put("water", new WaterTerrain());terrainTypes.put("mountain", new MountainTerrain());terrainTypes.put("road", new RoadTerrain());}public static Terrain getTerrain(String type) {Terrain terrain = terrainTypes.get(type.toLowerCase());if (terrain == null) {throw new IllegalArgumentException("未知的地形类型: " + type);}return terrain;}public static int getTerrainTypeCount() {return terrainTypes.size();}
}// 地形实例(包含外部状态)
class TerrainTile {private int x, y;private Terrain terrain;private String variation; // 外部状态:地形变种private boolean hasResource; // 外部状态:是否有资源public TerrainTile(int x, int y, Terrain terrain, String variation, boolean hasResource) {this.x = x;this.y = y;this.terrain = terrain;this.variation = variation;this.hasResource = hasResource;}public void render() {String instanceData = String.format("变种:%s, 资源:%s", variation, hasResource ? "有" : "无");terrain.render(x, y, instanceData);}public boolean isWalkable() {return terrain.isWalkable();}public int getMovementCost() {return terrain.getMovementCost();}// getterspublic int getX() { return x; }public int getY() { return y; }public String getVariation() { return variation; }public boolean hasResource() { return hasResource; }
}// 游戏地图类
class GameMap {private List<TerrainTile> tiles = new ArrayList<>();private int width, height;public GameMap(int width, int height) {this.width = width;this.height = height;}public void addTile(int x, int y, String terrainType, String variation, boolean hasResource) {if (x >= 0 && x < width && y >= 0 && y < height) {Terrain terrain = TerrainFactory.getTerrain(terrainType);tiles.add(new TerrainTile(x, y, terrain, variation, hasResource));}}public void render() {System.out.println("=== 渲染游戏地图 ===");System.out.println("地图大小: " + width + "x" + height);System.out.println("地形类型数量: " + TerrainFactory.getTerrainTypeCount());System.out.println("地形实例数量: " + tiles.size());for (TerrainTile tile : tiles) {tile.render();}}public List<TerrainTile> getWalkableTiles() {List<TerrainTile> walkableTiles = new ArrayList<>();for (TerrainTile tile : tiles) {if (tile.isWalkable()) {walkableTiles.add(tile);}}return walkableTiles;}
}// 客户端使用示例
public class GameMapDemo {public static void main(String[] args) {GameMap gameMap = new GameMap(100, 100);// 创建大量地形实例,但只有几种地形类型Random random = new Random();String[] terrainTypes = {"grass", "water", "mountain", "road"};String[] variations = {"light", "dark", "normal"};// 模拟创建一个大地图的地形for (int i = 0; i < 1000; i++) {int x = random.nextInt(100);int y = random.nextInt(100);String terrainType = terrainTypes[random.nextInt(terrainTypes.length)];String variation = variations[random.nextInt(variations.length)];boolean hasResource = random.nextDouble() < 0.1; // 10%概率有资源gameMap.addTile(x, y, terrainType, variation, hasResource);}// 渲染地图gameMap.render();// 获取可行走的地形List<TerrainTile> walkableTiles = gameMap.getWalkableTiles();System.out.println("\n可行走的地形数量: " + walkableTiles.size());// 显示前10个可行走地形System.out.println("\n前10个可行走地形:");for (int i = 0; i < Math.min(10, walkableTiles.size()); i++) {TerrainTile tile = walkableTiles.get(i);System.out.printf("位置(%d,%d), 变种:%s%n", tile.getX(), tile.getY(), tile.getVariation());}}
}
http://www.wxhsa.cn/company.asp?id=1897

相关文章:

  • # 数论知识讲解与C++代码:唯一分解定理、辗转相除法、埃氏筛与线性筛(含质因数分解示例)
  • 第九届交通工程与运输系统国际学术会议(ICTETS 2025)
  • 小红书开源 FireRedTTS-2;全栈开源应用+嵌入式+电路设计:BUDDIE AI 语音交互方案丨日报
  • 设计模式-外观模式 - MaC
  • 深度解析 ADC 偶联技术:从随机偶联到定点偶联,如何平衡抗肿瘤 ADC 的活性、稳定性与均一性?
  • 豆包P图大更新,网友们已经玩嗨了。
  • 【初赛】无向图度数性质 - Slayer
  • $p\oplus q=r$
  • 2025年金融行业API安全最佳实践:构建纵深防御体系
  • Jack-of-All-Trades
  • Matlab的交通标志定位实现
  • 怎样在 Salesforce Flow 中获取当前 Salesforce 组织的 URL
  • reLeetCode 热题 100-3 最长连续序列扩展 排序算法 - MKT
  • vuejs3.0 从入门到精通【左扬精讲】—— 从原生到原子化:一文梳理现代 CSS 技术体系(2025 版)
  • java中JSON字符串处理的踩坑
  • 11111
  • 阿里云微服务引擎 MSE 及 API 网关 2025 年 8 月产品动态
  • TIA Portal中S7-1500F CPU与ET200SP安全模块的配置例程(转载)
  • 获取第一个运行的Word应用程序实例
  • S7-1500 TRACE功能组态 (转载)
  • 如何在Proxmox VE中使用fdisk命令行扩展LVM存储池 - 若
  • 垃圾AV覆盖defender
  • SAP-PO:怎么控制传输的内容在单数据情况下是数组格式还是单对象格式
  • 开源新基建:数字中国创新发展的底层密码与生态实践
  • 员工离职停用Salesforce帐号?这11个“坑”千万别踩!
  • Linux的运行模式
  • Spring Boot + MybatisX,效率翻倍!
  • 条码控件Aspose.BarCode教程:使用 Java 自动生成 DotCode 条形码
  • AI 玩转网页自动化无压力:基于函数计算 FC 构建 Browser Tool Sandbox
  • AI时代的全栈框架:独立开发者的机会与挑战