【设计模式】二十二、享元模式

39 阅读3分钟

这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情

系列文章|源码

github.com/tyronczt/de…

定义-是什么

由来

面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式正是为解决这一类问题而诞生的。

享元模式(Flyweight Pattern)又称为轻量级模式,是对象池的一种实现。类似于线程池,线程池可以避免不停地创建和销毁多个对象,消耗性能。提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗,属于结构型模式。

定义

享元模式(Flyweight Pattern) :运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。

思考-为什么

适用场景

享元模式其实就是工厂模式的一个改进机制,享元模式同样要求创建一个或一组对象,并且就是通过工厂方法生成对象的,只不过享元模式中为工厂方法增加了缓存这一功能。

  • 常常应用于系统底层的开发,以便解决系统的性能问题

如:JAVA string,有则返回,无则创建 字符串,并放入缓存里 如:连接池

  • 系统有大量相似对象、需要缓冲池的场景

简单说:有大量需要被共享的时候,才有意义使用享元模式,否则就是杀鸡焉用牛刀

优点

  • 可以极大减少内存中对象的数量,使得相同或相似对象在内存中只保存一份,从而可以节约系统资源,提高系统性能。
  • 享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。

缺点

  • 享元模式使得系统变得复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
  • 为了使对象可以共享,享元模式需要将享元对象的部分状态外部化,而读取外部状态将使得运行时间变长。

应用-怎么用

源码 - Integer

java.lang.Integer#valueOf(int)

在范围内则从缓存中获取,这就是一个享元模式的使用

// range -128 to 127
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

参考

设计模式-享元模式学习之旅 - 掘金
享元模式 Flyweight | MRCODE-BOOK