Java设计模式 _结构型模式_享元模式

发布于:2024-05-11 ⋅ 阅读:(124) ⋅ 点赞:(0)

一、享元模式

1、享元模式
享元模式(Flyweight Pattern)是一种结构型模式。主要用于减少创建对象的数量,以减少内存占用和提高性能。主要解决有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
享元模式通过缓冲池的思路来实现,从而减少大量相同数据的产生,这样的数据要求内部状态不易变化,如游戏中的子弹,象棋中的棋子等。如果内部状态容易发生变化,就会很容器造成线程不安全的问题,这样的场景一般不推荐享元模式。

2、实现思路
(1)、定义享元接口。
(2)、编写实现享元接口的实现类。
(3)、编写享元工厂类(缓冲池如HashMap,获取享元对象的方法,其他处理缓冲池对象的方法)

二、代码示例

1、代码示例
获取象棋的棋子信息。一副中国象棋通常有很多棋子,每一个棋子的作用固定不发生变化,棋子存在一定的重复情况,如有多个炮,多个卒等。使用享元模式可以简化重复元素的创建。

// 1、定义享元接口
public interface ChineseChess {
    String getType();  // 类型
    String getDesc();  // 描述
}
// 2.1、定义享元实现类-马
public class Horse implements ChineseChess{
    @Override
    public String getType() {
        return "马";
    }
    @Override
    public String getDesc() {
        return "走日子形状,途径可吃掉其他棋子";
    }
}
// 2.2、定义享元实现类-炮
public class Cannon implements ChineseChess{
    @Override
    public String getType() {
        return "炮";
    }
    @Override
    public String getDesc() {
        return "走直线,间隔一个棋子打击其他棋子";
    }
}
// 3、创建享元工厂
import java.util.HashMap;
import java.util.Map;
public class ChineseChessFactory {
    private Map<String, ChineseChess> chessMap = new HashMap<>();

    public ChineseChess getChess(String type) {
        ChineseChess chess = null;
        if (chessMap.keySet().contains(type)) {
            chess = chessMap.get(type);
        } else {
            if ("马".equals(type)) {
                chess = new Horse();
            } else if ("炮".equals(type)) {
                chess = new Cannon();
            }
            chessMap.put(type, chess);
        }
        return chess;
    }

    public void removeChess(String type) {
        chessMap.remove(type);
    }
}
// 4、测试
public static void main(String[] args) {
        ChineseChessFactory chessFactory = new ChineseChessFactory();

        ChineseChess chess = chessFactory.getChess("马");
        ChineseChess chess2 = chessFactory.getChess("马");
        chessFactory.removeChess("马");
        ChineseChess chess3 = chessFactory.getChess("马");
        System.out.println(chess);
        System.out.println(chess2);
        System.out.println(chess3);

        ChineseChess chess1 = chessFactory.getChess("炮");
        System.out.println(chess1);
    }

运行结果:
在这里插入图片描述

总结:
当一个类内部不易变化,且这种类需要大量的创建和销毁时,可以使用享元模式去优化内存和提升性能。主要套路就3步,创建接口,创建实例,创建工厂。工厂内部通过缓存的方式(HashMap,redis等)保存了已经创建过的对象,再次获取时直接走缓存返回。有点类似单例模式和工厂模式的结合,但是享元又不一定是单例的,所以具体使用还要看场景需要。

学海无涯苦作舟!!!


网站公告

今日签到

点亮在社区的每一天
去签到