运用共享技术有效的支持大量细粒度的对象。 有点像对象可以变的单例。
享元模式 Flyweight
问题:
Designing objects down to the lowest levels of system “granularity” provides optimal flexibility, but can be unacceptably expensive in terms of performance and memory usage.
意图:
- Use sharing to support large numbers of fine-grained objects efficiently.
- The Motif GUI strategy of replacing heavy-weight widgets with light-weight gadgets.
代码
例: (其它JAVA里面的多线程的锁就是一个明显的享元模式,锁为多个线程中的一个共享对象)比如玩连连看开局时,如果一屏有10X10个方块,方块类型各不相同,你或者会想先NEW100个普通方块,再遍历一次每个方块设置属性,也许是对种方块对应不同的Class类,先计算好方块类型,遍历时根据索引选择NEW的对象,这样当然没有什么问题。可是使用享元模式,可以先NEW一百个普通的方块,在NEW的过程中设置方块的类型。
代码1:服务构造画布的类
import java.util.ArrayList;
import java.util.List;
/**
* @author xdnote.com
* 服务端的类
* 对客户端提供一个bulid方法,内在一个共享的类型对象(享元模式核心,每个实例化的方块都会调用这个对象并修改)
* 对对象提供getType方法(protected)
* */
public class Server {
private static List<Integer> types = new ArrayList<Integer>();
protected static int getType(){
int size = types.size();
int index = ((int)Math.ceil(Math.random()*100))%size;
int type = types.get(index);
types.remove(index);
return type;
}
private static void buildTypes(int rowNum, int colNum, int typeNum){
for(int i = 0, total = rowNum * colNum ;i<total; i++){
int type = ((int)Math.ceil(Math.random()*100))%typeNum +1;
types.add(type);
}
}
public static void buildMap(int rowNum, int colNum, int typeNum){
buildTypes(rowNum,colNum,typeNum);
for(int i = 0;i<rowNum;i++){
for(int j=0;j<colNum;j++){
Tab tab = new Tab(i,j);
System.out.println(" ROW:"+ tab.getRowNum()+" COL:"+tab.getColNum()+" TYPE:"+tab.getType());
}
}
}
}
代码二:每个格式了实体
/**
* @author xdnote.com
* 方块类
* */
public class Tab {
private int rowNum;
private int colNum;
private int type;
public Tab(int rowNum, int colNum) {
this.rowNum = rowNum;
this.colNum = colNum;
this.type = Server.getType();
}
public int getRowNum() {
return rowNum;
}
public int getColNum() {
return colNum;
}
public int getType() {
return type;
}
}
代码三:客户端使用
/**
* @author xdnote.com
* 享元模式,看名字和概念貌似十分复杂,个人理解为,一个对象有很多种状态,通过一个共享对象来维护,每个对象对应一个或多个场景.
* 比如画一个连连看的开局,10X10的格子,难度为5(5种不同的方块,两种类型一样才能连接)
* */
public class Client {
public static void main(String[] args){
Server.buildMap(10,10,5);
}
}
小结
享元模式 Flyweight
- 使用频率:
低
对于web的实际编程中,使用享元模式是很低的,但对于游戏编程来说,是非常说的,特别是图形绘制时,你都不需要new就可以用一个对象不停的换出方形圆形等。
- 利弊影响:
高
对每个状态的存档都要计算好了,不然容易出BUG,而且代码较难看,不写注释的话,过几天就看不懂了