• 【结构型】享元模式


    享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象(不能暴露任何set()等修改内部状态的方法)。

    具体来讲,当一个系统中存在大量重复对象的时候,如果这些重复的对象是不可变对象,我们就可以利用享元模式将对象设计成享元,在内存中只保留一份实例,供多处代码引用。这样可以减少内存中对象的数量,起到节省内存的目的。实际上,不仅仅相同对象可以设计成享元,对于相似对象,我们也可以将这些对象中相同的部分(字段)提取出来,设计成享元,让这些大量相似对象引用这些享元。

    应用:多个游戏大厅中棋子的内存共享、Java中Integer的包装类的实现

    利用工厂类来缓存ChessPieceUnit信息(也就是id、text、color)。通过工厂类获取到的ChessPieceUnit就是享元。所有的ChessBoard对象共享这30个ChessPieceUnit对象(因为象棋中只有30个棋子)。在使用享元模式之前,记录1万个棋局,我们要创建30万(30*1万)个棋子的ChessPieceUnit对象。利用享元模式,我们只需要创建30个享元对象供所有棋局共享使用即可,大大节省了内存。

    代码实现非常简单,主要是通过工厂模式,在工厂类中,通过一个Map来缓存已经创建过的享元对象,来达到复用的目的。

    // 享元类
    public class ChessPieceUnit {
      private int id;
      private String text;
      private Color color;
    
      public ChessPieceUnit(int id, String text, Color color) {
        this.id = id;
        this.text = text;
        this.color = color;
      }
    
      public static enum Color {
        RED, BLACK
      }
    
      // ...省略其他属性和getter方法...
    }
    
    public class ChessPieceUnitFactory {
      private static final Map<Integer, ChessPieceUnit> pieces = new HashMap<>();
    
      static {
        pieces.put(1, new ChessPieceUnit(1, "車", ChessPieceUnit.Color.BLACK));
        pieces.put(2, new ChessPieceUnit(2,"馬", ChessPieceUnit.Color.BLACK));
        //...省略摆放其他棋子的代码...
      }
    
      public static ChessPieceUnit getChessPiece(int chessPieceId) {
        return pieces.get(chessPieceId);
      }
    }
    
    public class ChessPiece {
      private ChessPieceUnit chessPieceUnit;
      private int positionX;
      private int positionY;
    
      public ChessPiece(ChessPieceUnit unit, int positionX, int positionY) {
        this.chessPieceUnit = unit;
        this.positionX = positionX;
        this.positionY = positionY;
      }
      // 省略getter、setter方法
    }
    
    public class ChessBoard {
      private Map<Integer, ChessPiece> chessPieces = new HashMap<>();
    
      public ChessBoard() {
        init();
      }
    
      private void init() {
        chessPieces.put(1, new ChessPiece(
                ChessPieceUnitFactory.getChessPiece(1), 0,0));
        chessPieces.put(1, new ChessPiece(
                ChessPieceUnitFactory.getChessPiece(2), 1,0));
        //...省略摆放其他棋子的代码...
      }
    
      public void move(int chessPieceId, int toPositionX, int toPositionY) {
        //...省略...
      }
    }
    View Code
  • 相关阅读:
    linux下最简单的端口转发工具
    FRP 简单入门安装配置教程
    Linux上创建SSH隧道
    微信公众平台 · 小程序文档
    windows 10
    高清方法生成缩略图函数
    用python的turtle画图
    python安装包下载
    nginx 报invalid pid number
    derby数据库windows自带的客户端
  • 原文地址:https://www.cnblogs.com/clarino/p/15717280.html
Copyright © 2020-2023  润新知