Java设计模式之从[Dota地图]分析享元(Flyweight)模式
来源:互联网 发布:python https请求 编辑:程序博客网 时间:2024/05/14 15:50
在Dota游戏的地图中有几百棵树,现在假设这些树木无非是这两种:白杨、枫树,数量一共为400棵,那么,在装载这个地图场景的时候,我们是不是应该给这400课树一一建立对象呢?(如:MapItem tree1 = new MapItem("白杨");MapItem tree2 = new MapItem("枫树");MapItem tree3 = new MapItem("白杨");……)哪怕这些语句写在循环中减少了我们代码书写的工作量,对于系统来说,是十分消耗资源的一件事情,因为系统要生成400个对象。可见这样十分影响效率。那么,我们能不能用一些优化技术呢?当然可以,那就是使用“享元模式”。如果看到这里还不明白的话,接着往下看就能够明白了。
享元模式的意图是运用共享技术有效地支持大量细粒度的对象。在上面的例子中,我们把所有的同一种类的树指向同一个对象,这样可以来节省内存的使用,提高程序效率,请看以下代码:
interface FlyweightItem { void draw();}class FlyweightMapItem implements FlyweightItem { String name; public FlyweightMapItem(MapItem map){ this.name = map.name; } public void draw(){ System.out.printf("正在绘制%s\n", name); }}class MapItem { String name; public MapItem(String name){ this.name = name; }}class FlyweightMapFactory { private static FlyweightMapFactory flyweightMapFactory = new FlyweightMapFactory(); private HashMap<String, FlyweightMapItem> itemMap = new HashMap<String, FlyweightMapItem>(); private int itemCount = 0; public int getItemCount(){ return itemCount; } public static FlyweightMapFactory getFlyweightMapFactory(){ return flyweightMapFactory; } public FlyweightMapItem getItem(MapItem item){ if (itemMap.containsKey(item.name)){ return itemMap.get(item.name); } else { FlyweightMapItem map = new FlyweightMapItem(item); itemCount ++; itemMap.put(item.name, map); return map; } }}class Flyweight{ public static void main(String[] args) { FlyweightItem item1 = FlyweightMapFactory.getFlyweightMapFactory().getItem(new MapItem("枫树")); FlyweightItem item2 = FlyweightMapFactory.getFlyweightMapFactory().getItem(new MapItem("枫树")); FlyweightItem item3 = FlyweightMapFactory.getFlyweightMapFactory().getItem(new MapItem("白杨")); FlyweightItem item4 = FlyweightMapFactory.getFlyweightMapFactory().getItem(new MapItem("枫树")); item1.draw(); item2.draw(); item3.draw(); item4.draw(); System.out.println("享元中拥有的对象数量为:"); System.out.println(FlyweightMapFactory.getFlyweightMapFactory().getItemCount()); }}
假设我们正在做一个地图编辑器,所有的地图元素都是MapItem类,其中的name表示这个地图元素的名称,我们用它来判断是否两个元素为同一元素。MapItem对象可作为参数传给FlyweightMapItem对象,FlyweightMapItem有一个draw方法,表示把这个元素绘制出来。FlyweightMapFactory是用于判断元素唯一性的一个工厂类,它内部有一个Map来记录元素是否已经生产过,在调用getItem时,如果对象已经生产过,则直接返回生产的对象,否则,新建一个对象,并将它加入Map中然后返回。由于工厂在本例中必须唯一,因此它采用的是单例模式。
最后,输出的结果为:
正在绘制枫树
正在绘制枫树
正在绘制白杨
正在绘制枫树
享元中拥有的对象数量为:
2
可见,虽然我们建立了item1、item2、item3、item4,但是由于item1、item2、item4都是枫树,在享元模式中,它们共享着同一个对象,因此有item1==item2==item4,那么,整个系统中,真正拥有的对象数量也就只有2个了,分别是枫树和白杨。
以上便是享元模式的一个简单应用。享元模式会增加程序的复杂程度,但是会增加程序的效率(在上面的例子中,虽然新建了MapItem对象,但是它很快就被垃圾回收了)。享元模式的应用有:Java的String类型(如String a= "123"; String b="123"; 最后发现a==b,说明Java的String类型是享元模式的),以及文字处理系统中字符的处理方法(这个是显然的,假设一篇文章有10万个字,不可能建立10万个对象的,它需要用到享元模式来减少开支)。享元模式通常包含共享部分和非共享部分,非共享部分通常作为共享部分的父节点。
- Java设计模式之从[Dota地图]分析享元(Flyweight)模式
- java设计模式之享元模式Flyweight
- Java设计模式之--享元模式(Flyweight Pattern)
- JAVA设计模式之享元模式Flyweight
- Java语言设计模式之享元模式(Flyweight)
- 设计模式之Flyweight享元模式
- 【设计模式】之 Flyweight享元模式
- 设计模式之享元模式(Flyweight)
- 设计模式之享元模式(Flyweight)
- 设计模式之享元模式Flyweight
- Java设计模式-----FlyWeight享元模式
- Java 享元模式(Flyweight) 设计模式
- Java设计模式-----FlyWeight享元模式
- 设计模式之Flyweight(享元) FlyWeight模式
- 设计模式之Flyweight(享元) FlyWeight模式
- 设计模式之Flyweight(享元) FlyWeight模式
- 设计模式之Flyweight(享元) FlyWeight模式
- 设计模式之Flyweight(享元) FlyWeight模式
- 创建App.config配置文件的连接字符串
- google高级搜索命令
- Python学习笔记(3)事件驱动模型,frame, button
- 全排列生成法(6种),字典序
- 揭密微软游戏云计算技术
- Java设计模式之从[Dota地图]分析享元(Flyweight)模式
- poj 2159
- 一步一步写算法(之图添加和删除)
- HDU A new Graph Game(费用流)
- Effective C++——》条款20:宁以pass by refrence to const 替换 pass by value
- OK6410学习之遇到的问题与C语言实现 流水灯
- A famous music composer
- hibernate初学简单实例
- C++内存分配方式详解——堆、栈、自由存储区、全局/静态存储区和常量存储区