当前位置: 首页 > article >正文

Java设计模式之享元模式

概念

享元模式是一种结构型设计模式,通过共享对象来减少内存占用和对象创建开销。它将对象状态分为:

1.内部状态(Intrinsic):可共享的、不变的部分(如颜色)。

2.外部状态(Extrinsic):不可共享的、变化的部分(如位置、半径)。

作用

1.减少重复对象的创建,降低内存消耗。

2.提高系统性能(对象初始化成本高时效果显著)。

使用场景

1.系统需要创建大量相似对象。

2.对象的大部分状态可以外部化。

3.需要缓存或对象池的场景(如游戏中的粒子系统、文档编辑器中的字符对象)。

举例

// 享元接口
interface Circle {
    void draw(int x, int y, int radius);
}
// 具体享元类
class ConcreteCircle implements Circle {
    private final String color; // 内部状态(共享)

    public ConcreteCircle(String color) {
        this.color = color;
    }

    @Override
    public void draw(int x, int y, int radius) { // 外部状态作为参数
        System.out.printf("Drawing %s circle at (%d,%d) with radius %d\n", 
                         color, x, y, radius);
    }
}
// 享元工厂
class CircleFactory {
    private static final Map<String, Circle> circleMap = new HashMap<>();

    public static Circle getCircle(String color) {
        // 如果没有生成特定颜色的圆,则生成并保存,最后再返回
        if (!circleMap.containsKey(color)) {
            Circle newCircle = new ConcreteCircle(color);
            circleMap.put(color, newCircle);
        } 
        return circleMap.get(color);
    }
}
// 客户端使用
public class Client {
    public static void main(String[] args) {
        String[] colors = {"Red", "Blue", "Green"};
        
        // 获取10个圆形,但实际只创建3个对象
        for(int i=0; i<10; i++){
            String color = colors[i % 3];
            Circle circle = CircleFactory.getCircle(color);
            circle.draw(i*10, i*20, 5); // 外部状态每次不同
        }
    }
}

优点和缺点

优点

1.减少内存使用。

2.提高性能(减少GC压力)。

3.适用于大量相似对象的场景。

缺点

1.增加系统复杂性。

2.需要区分内部/外部状态。

3.可能引入线程安全问题。

未使用享元模式的实现

class SimpleCircle {
    private String color;
    
    public SimpleCircle(String color) {
        this.color = color;
    }
    
    public void draw(int x, int y, int radius) {
        System.out.printf("Drawing %s circle at (%d,%d) with radius %d\n", 
                         color, x, y, radius);
    }
}
public class Client {
    public static void main(String[] args) {
        String[] colors = {"Red", "Blue", "Green"};
        
        // 每次都会创建新对象(共创建10个对象)
        for(int i=0; i<10; i++){
            String color = colors[i % 3];
            SimpleCircle circle = new SimpleCircle(color); // 每次都新建对象
            circle.draw(i*10, i*20, 5);
        }
    }
}

总结

1.享元核心:通过对象复用将对象数量从使用次数级别降低到不同状态组合级别。

2.取舍判断:当对象初始化成本高且存在大量重复状态时优先使用。

3.状态管理:需要仔细区分类的固有属性和运行时可变属性。

4.性能影响:在需要创建数百万个对象的场景中,内存节省效果会非常显著。

实际开发中,Java的String常量池、Integer.valueOf()缓存(-128~127)都是享元模式的经典应用。

享元模式和单例模式的区别

特征

享元模式

单例模式

核心目标

通过共享多个对象减少内存占用

确保全局唯一对象

对象数量

按内部状态分类创建多个共享对象

整个系统只存在一个实例

状态管理

区分内部状态(共享)和外部状态

通常不区分状态,或状态全局共享

创建方式

工厂根据参数返回不同共享对象

静态方法返回唯一实例

适用场景

需要管理大量相似对象的场景

需要全局唯一访问点的场景

典型应用

游戏粒子系统、文档编辑器字符对象

数据库连接池、配置管理器、日志工具


http://www.kler.cn/a/593011.html

相关文章:

  • 【深度学习与大模型基础】第7章-特征分解与奇异值分解
  • Docker build 会在本地产生巨大的文件
  • vue3计算当前日期往前推一个月的日期,当前日期往前推7天
  • 用 C 语言理解封装、继承、多态
  • 单机 elasticsearch下载,安装,配置,启动,百度云链接提供
  • 技术视界 | 灵巧手的工作空间:解锁机器人精细操作的无限可能
  • PHP工程师转向Java开发定制的教材及教程信息,结合两种语言的差异点进行针对性推荐
  • 【计算机网络】2物理层
  • 群体智能优化算法-黏菌优化算法(Slime Mould Algorithm, SMA,含Matlab源代码)
  • vmware tools灰化
  • 如何排查和修复 MSSQL 数据库连接失败的问题
  • 【模拟】扫雷
  • 【机器学习】算法分类
  • Python个人学习笔记(18):模块(异常处理、traceback、日志记录)
  • 蓝桥杯备考:奶牛晒衣服
  • 【为什么游戏能使人上瘾】
  • FPGA中级项目5——VGA part1
  • ChatGPT推理模型通用模型大解析!
  • v-on=“$listeners“ 这个写法已经废弃了,如进行代替
  • 基于python+django+mysql的小区物业管理系统源码+运行步骤