1. 设计模式之享元模式:简单的jvm内存对象池缓存

1.1. 介绍

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。

享元可以理解为 享受 元数据;同一个数据,可以认为是一个元数据,整个系统里这个数据就一份,缓存起来。实际项目中,例如权限数据,读多写少,数据简单,就可以使用享元模式。

享元模式 vs 单例模式

对比维度 享元模式 单例模式
目的 共享多个相似对象。 全局唯一实例。
对象数量 多个(按需共享)。 仅一个。
状态管理 分离内部状态和外部状态。 通常无状态或全局状态。

应用场景

  1. 游戏开发:大量重复的游戏对象(如子弹、NPC、粒子效果)。

  2. 图形渲染:文本编辑器中的字符、表格单元格样式。

  3. 数据库连接池:复用连接对象而非频繁创建。

  4. 线程池/对象池:复用线程或资源密集型对象。

优缺点及建议

优点
1.显著减少内存占用。
2.提升性能(减少对象创建开销)。
3.适合高频使用的轻量级对象。

缺点
1.增加代码复杂度(需分离内外状态)。
2.共享对象可能导致线程安全问题。

使用建议
1.在创建大量相似对象时考虑使用享元模式。
2.确保享元对象的内部状态是共享的,而外部状态是独立于对象的。

注意事项
1.使用工厂类集中管理共享对象(如`Map`缓存)。  
2.确保内部状态是 不可变 的(避免共享冲突)。  
3.外部状态应尽量简单(如坐标、颜色)。

1.2. 实现及相关代码

假设有一个业务,缓存某数据对象,同一份数据,只有一份。

1.2.1. 相关代码

接口及数据对象

public static interface Flyweight {
    void execute();
    String getName();
    void setName(String name);
}

public static class ConcreteFlyweight implements Flyweight {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ConcreteFlyweight(String name) {
        super();
        this.name = name;
    }

    public void execute() {
        System.out.println(name + "执行功能逻辑");
    }
}

public static class FlyweightFactory {
    private static Map<String, Flyweight> cachePool = new HashMap<String, Flyweight>();

    public static Flyweight get(String name) {
        Flyweight flyweight = cachePool.get(name);
        if(flyweight == null) {
            flyweight = new ConcreteFlyweight(name);
            cachePool.put(name, flyweight);
        }
        return flyweight;
    }
}

调用方法

public static void main(String[] args) {
    Flyweight flyweight1 = FlyweightFactory.get("对象1");
    flyweight1.execute();

    Flyweight flyweight2 = FlyweightFactory.get("对象1");
    flyweight2.execute();

    System.out.println(flyweight1 == flyweight2);
}

results matching ""

    No results matching ""