java设计模式之享元模式

享元顾名思义共享单元

比如在网上围棋游戏中,可能同时有很多人在下棋,每个棋局一个棋盘+N个棋子。

如果有一百万人同时在线,每个棋局数百个棋子,那就需要上亿的棋子对象,这个显然是一种浪费。

因为棋子非黑即白,没有什么变化,这些棋子在不同的棋盘都可以共享的

我们首先定义一个棋子类,它只有颜色一个属性

public enum Color {
    WHITE,
    BLACK;
}

我们定义一个棋子类,它有颜色和ID两个属性

/**
 * 围棋棋子
 */
public class GoPiece {

    private Color color;
    private Integer id;

    public  GoPiece(Color color, Integer id) {
        this.color = color;
        this.id = id;
    }
}

 

在一个围棋棋盘上,每个棋子都是不同的,所以我们需要给围棋棋子定义一个ID,黑子共181个,白子180个,我们定义一个工厂类来生成

/**
 * 围棋棋子工厂类
 */
public class GoPieceFactory {
    private static final int blackNum=181;
    private static final int whiteNum=180;
    private static final List<GoPiece> blackPieces = new ArrayList<>();
    private static final List<GoPiece> whitePieces = new ArrayList<>();

    static {
        for (int i = 0; i < blackNum; i++) {
            blackPieces.add(i, new GoPiece(Color.BLACK, i));
        }
        for (int j = 0; j < whiteNum; j++) {
            whitePieces.add(j, new GoPiece(Color.WHITE, j));
        }
    }

    public static GoPiece getWhite() {
        Random random = new Random();
        int i = random.nextInt(whiteNum);
        return whitePieces.get(i);
    }

    public static GoPiece getBlack() {
        Random random = new Random();
        int i = random.nextInt(blackNum);
        return blackPieces.get(i);
    }
}

接下来就可以下棋了

/**
 * 围棋游戏
 */
public class GoGame {
    private Table<Integer,Integer,GoPiece> board= HashBasedTable.create();

    public GoGame() {
       init();
    }

    private void init(){
        board.put(0,0,GoPieceFactory.getBlack());//执黑先行
        board.put(0,1,GoPieceFactory.getWhite());
        board.put(1,1,GoPieceFactory.getBlack());
        //...
    }
}

不管有多少棋局同时在线,棋子就是工厂里这361个对象。相对于上亿的对象,极大减少了内存空间的使用。

 

上一篇:BFS宽度优先搜索


下一篇:Java自定义线程池