自学内容网 自学内容网

享元模式(结构型)

目录

一、前言

二、享元模式

三、总结


一、前言

        享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少大量细粒度对象的内存占用。它通过共享尽可能多的相同数据来节约内存空间。

        享元模式由以下角色组成:

Flyweight(享元):

一个接口或抽象类,定义了对象的外部状态和内部状态的方法

ConcreteFlyweight(具体享元):

实现享元接口的具体类,包含享元对象的内部状态

UnsharedConcreteFlyweight(非享元):

不需要共享的对象

FlyweightFactory(享元工厂):

创建和管理享元对象,确保共享的享元对象被正确地使用

        整个享元模式的结构图:

二、享元模式

        我们可以以围棋为例,围棋坐标是19*19=361,围棋只有两种颜色,黑色和白色,有很多棋子,此时我们可以利用享元模式,所有黑棋共享一个对象,所有白棋共享一个对象,棋子格子的位置不同,因此位置可以设置为不共享的对象。

        首先创建围棋享元接口类GoPiece.class:

/**
 * @Author dengyifan
 * @create 2024/7/24 14:26
 * @description 享元接口
 */
public interface GoPiece {
    String getColor();

    void place(int x, int y);
}

        再创建黑棋对象BlackPiece.class:

/**
 * @Author dengyifan
 * @create 2024/7/24 14:26
 * @description 具体享元类,黑棋
 */
public class BlackPiece implements GoPiece{
    private final String color = "Black";

    @Override
    public String getColor() {
        return color;
    }

    @Override
    public void place(int x, int y) {
        System.out.println("棋子:" + color + ",位置信息:(" + x + ", " + y + ")");
    }
}

        白棋对象WhitePiece.class:

/**
 * @Author dengyifan
 * @create 2024/7/24 14:26
 * @description 具体享元类,白棋
 */
public class WhitePiece implements GoPiece{
    private final String color = "White";

    @Override
    public String getColor() {
        return color;
    }


    @Override
    public void place(int x, int y) {
        System.out.println("棋子:" + color + ",位置信息:(" + x + ", " + y + ")");
    }
}

        编写享元工厂GoPieceFactory.class:

import java.util.HashMap;
import java.util.Map;

/**
 * @Author dengyifan
 * @create 2024/7/24 14:26
 * @description 享元工厂
 */
public class GoPieceFactory {
    private static final Map<String, GoPiece> pieceMap = new HashMap<>();

    public static GoPiece getPiece(String color) {
        GoPiece piece = pieceMap.get(color);
        if (piece == null) {
            if (color.equalsIgnoreCase("Black")) {
                piece = new BlackPiece();
            } else if (color.equalsIgnoreCase("White")) {
                piece = new WhitePiece();
            }
            pieceMap.put(color, piece);
        }
        return piece;
    }
}

        棋盘类BoardPosition.class:

/**
 * @Author dengyifan
 * @create 2024/7/24 14:29
 * @description 棋盘位置类,包含享元对象和位置,共享GoPiece对象,以及不共享的x、y位置信息
 */
public class BoardPosition {
    private final int size;
    private final GoPiece[][] board;

    public BoardPosition(int size) {
        this.size = size;
        this.board = new GoPiece[size][size];
    }

    public void placePiece(String color, int x, int y) {
        GoPiece piece = GoPieceFactory.getPiece(color);
        board[x][y] = piece;
        piece.place(x, y);
    }

    public void printBoard() {
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                if (board[i][j] != null) {
                    System.out.print(board[i][j].getColor().charAt(0) + " ");
                } else {
                    System.out.print(". ");
                }
            }
            System.out.println();
        }
    }

    public GoPiece getPieceAt(int x, int y) {
        return board[x][y];
    }
}

         客户端调用类:

/**
 * @Author dengyifan
 * @create 2024/7/24 14:27
 * @description
 */
public class Client {
    public static void main(String[] args) {
        BoardPosition board = new BoardPosition(19);

        board.placePiece("Black", 1, 2);
        board.placePiece("White", 2, 3);
        board.placePiece("Black", 3, 4);
        board.placePiece("White", 4, 5);

        board.printBoard();

        GoPiece piece1 = board.getPieceAt(1, 2);
        GoPiece piece2 = board.getPieceAt(2, 3);
        GoPiece piece3 = board.getPieceAt(3, 4);
        GoPiece piece4 = board.getPieceAt(4, 5);

        System.out.println("棋子1和棋子3: " + (piece1 == piece3));
        System.out.println("棋子2和棋子4: " + (piece2 == piece4));
    }
}

        运行结果:

三、总结

        优点与缺点

优点:

减少对象数量:

通过共享技术可以有效减少内存中的对象数量,从而提高系统的性能

节约内存:

共享的享元对象能够极大地节约内存空间

缺点:

复杂性增加:

系统中引入了享元工厂和共享机制,增加了系统的复杂性

非共享对象:

并不是所有的对象都适合使用享元模式,对于那些包含大量不变数据的对象,享元模式才有明显的优势

        应用场景:

文本编辑器:

在文本编辑器中,每个字符可以看作是一个对象。如果文档非常大,这些字符对象将占用大量内存。使用享元模式,可以将相同字符的对象共享起来,显著减少内存消耗

图形系统:

在图形系统中,经常需要绘制大量相同或相似的图形元素,如点、线、圆等。通过享元模式,可以将相同的图形对象共享,以节约内存

数据库连接池:

在数据库应用中,创建和销毁数据库连接的开销很大。使用享元模式,可以创建一个数据库连接池,所有的数据库连接都从池中获取和释放,从而提高性能和资源利用率

游戏开发:

在游戏开发中,大量的游戏对象(如树木、建筑物、NPC等)需要频繁使用。使用享元模式,可以将相同类型的游戏对象共享,从而减少内存占用,提高游戏性能


原文地址:https://blog.csdn.net/qq_41061437/article/details/140653629

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!