2023-03-27
原文作者:ClarenceZero 原文地址:https://blog.csdn.net/ClarenceZero/article/details/106915912

享元模式

定义

所谓享元,顾名思义就是被共享的单元。享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。在内存中只保留一份实例,供多处代码引用。

实现

1. 定义享元类

    /**
     * 享元类
     * 这里定义的字段都是可以复用的
     */
    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;
        }
    }

2.定义享元工厂

    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(1, "馬", ChessPieceUnit.Color.BLACK));
        }
    
        public static ChessPieceUnit getChessPiece(int chessPieceId) {
            return pieces.get(chessPieceId);
        }
    }

3.定义棋盘

    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(2, new ChessPiece(ChessPieceUnitFactory.getChessPiece(2), 0, 0));
        }
    
        public void move(int chessPieceId, int toPositionX, int toPositionY) {
            System.out.println("move");
        }
    }

总结

  1. 代码结构主要是通过工厂模式,在工厂类中通过一个Map对象缓存已创建过的享元对象,从而达到复用的目的。
  2. 应用享元模式目的是为了对象复用,节省内存。
  3. 池化技术的复用可以理解为重复使用,主要目的是节省时间(比如从数据库池中取一个连接,不需要重新创建)。在任意时刻,每一个对象、连接、线程,并不会被多处使用,而是被一个使用者独占,当使用完成之后,放回到池中,再由其他使用者重复利用。享元模式中的复用可以理解为共享使用,在整个生命周期中,都是被所有使用者共享的,主要目的是节省空间。
  4. 实际上,不仅仅相同对象可以设计成享元,对于相似对象,我们也可以将这些对象中相同的部分(字段),提取出来设计成享元,让这些大量相似对象引用这些享元。
阅读全文