什么是享元模式?
运用共享技术有效地支持大量细粒度的对象。重用现有的同类对象,如果未找到匹配的对象,则创建新对象。主要用于减少创建对象的数量,以减少内存占用和提高性能。
适用场景
代码实现
示例:围棋,围棋的棋子可以简化为两个对象,黑棋和白棋,不同的是棋子的坐标。
/*** 棋子*/class Piece {protected Color color;//颜色protected int x;//x坐标protected int y;//y坐标public Piece(Color color, int x, int y) {this.color = color;this.x = x;this.y = y;}@Overridepublic String toString() {return "棋子:" + color + ",横坐标:" + x + ",纵坐标:" + y;}}/*** 枚举 棋子类型*/enum Color {Black,White;}/*** 棋子工厂类,实现对象共享*/class PieceFactory {private static final Map<Color, Piece> map = new ConcurrentHashMap<>();public synchronized static Piece getPiece(@NotNull Color color, int x, int y) {Piece piece = map.get(color);if (null == piece) {piece = new Piece(color, x, y);map.put(color, piece);}System.out.println("内存占用:" + map.size());return piece;}}/*** 组合模式测试*/public class FlyweightPattern {public static void main(String[] args) {//模拟棋盘 100*100final int width = 100;final int high = 100;//随机获取一百个棋子final int count = 100;//两个线程 模拟两个人对弈//对弈者1new Thread(() -> {Random random = new Random();for (int i = 0; i < count; i++) {int x = random.nextInt(width);int y = random.nextInt(high);Piece piece = null;//利用奇数偶数模拟黑白棋子if (i % 2 != 0) {//奇数 白棋piece = PieceFactory.getPiece(Color.White, x, y);} else {piece = PieceFactory.getPiece(Color.Black, x, y);}System.out.println(piece);}}).start();//对弈者2new Thread(() -> {Random random = new Random();for (int i = 0; i < count; i++) {int x = random.nextInt(width);int y = random.nextInt(high);Piece piece = null;//利用奇数偶数模拟黑白棋子if (i % 2 != 0) {//奇数 白棋piece = PieceFactory.getPiece(Color.White, x, y);} else {piece = PieceFactory.getPiece(Color.Black, x, y);}System.out.println(piece);}}).start();//输出://内存占用:1//内存占用:1//棋子:Black,横坐标:43,纵坐标:52//棋子:Black,横坐标:43,纵坐标:52//内存占用:2//棋子:White,横坐标:88,纵坐标:68//内存占用:2//棋子:White,横坐标:88,纵坐标:68//内存占用:2//棋子:Black,横坐标:43,纵坐标:52//内存占用:2//棋子:Black,横坐标:43,纵坐标:52//内存占用:2//棋子:White,横坐标:88,纵坐标:68//内存占用:2//棋子:White,横坐标:88,纵坐标:68//内存占用:2//棋子:Black,横坐标:43,纵坐标:52//内存占用:2//棋子:Black,横坐标:43,纵坐标:52//内存占用:2//棋子:White,横坐标:88,纵坐标:68//内存占用:2//棋子:White,横坐标:88,纵坐标:68//内存占用:2//棋子:Black,横坐标:43,纵坐标:52//内存占用:2//棋子:Black,横坐标:43,纵坐标:52//.....}}
