X.d 笔记

小Web,大世界

0%

设计模式(11):享元模式 Flyweight

运用共享技术有效的支持大量细粒度的对象。 有点像对象可以变的单例。

享元模式 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,而且代码较难看,不写注释的话,过几天就看不懂了