zoukankan      html  css  js  c++  java
  • 【结构型】享元模式

    享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象(不能暴露任何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
  • 相关阅读:
    supervisor(一)基础篇
    linux添加开机自启动脚本示例详解
    suse 不能远程登录
    LintCode,hihoCoder,LeetCode有什么区别?
    windows 下安装nodejs 要怎么设置环境变量
    Java 集合:HashSet 与 ArrayList
    Java ArrayList、Vector和LinkedList等的差别与用法(转)
    一行代码实现java list去重
    25 highest paying companies: Which tech co outranks Google, Facebook and Microsoft?
    Chart: Who pays the most in Seattle for software engineers
  • 原文地址:https://www.cnblogs.com/clarino/p/15717280.html
Copyright © 2011-2022 走看看