享元模式——java设计模式(十三)

简介

享元模式(Flyweight Pattern):运用共享技术有效的支持大量细粒度对象的复用。

  • 当系统中存在大量相同或者相似的细粒度对象时,可以共享这些对象。将具有相同内部状态的对象存储在享元池中,取出时注入不同的外部状态则可以得到相似的对象。
    • 内部状态:存储在享元内部。不会随环境改变,可以共享。
    • 外部状态:通常由客户端保存,使用时传入享元内部。随环境改变,不可以共享。

结构和实现

  • 角色包括:
    • 抽象享元类:声明具体享元类的业务方法,可以提供内部状态,也可以注入外部状态。
    • 具体享元类:实现抽象享元类,存储内部状态,通常可以使用单例以确保对象唯一。
    • 非共享具体享元类:实现抽象享元类,但是不能共享,需要时可以直接创建。
    • 享元工厂类:创建并管理享元对象,针对抽象享元类编程,通常可以使用工厂模式。
  • 享元模式结构。
    180508.flyweight.png

实例

  • 开发围棋软件,大量黑子和白子只有出现的位置不一样,其他相同。需要减少运行时占据的内存空间。
    180508.chessman.png

单纯享元模式

  • 不存在非共享的具体享元类。
    180508.singel.png

复合享元模式

  • 将单纯享元对象通过组合模式组合成复合享元对象,从而形成树形结构。符合享元对象不能共享,但是组成它们的单纯享元对象可以共享。
  • 复合享元类包含的单纯享元类具有相同的外部状态
    180508.compos.png

优缺点和适用环境

  • 优点:
    • 减少对象数量。相同或相似对象只保留一份,节约资源、提高性能。
    • 可在不同环境中共享。内部状态不变,外部状态不影响内部状态。
  • 缺点:
    • 系统复杂。分离内部和外部状态,逻辑复杂化。
    • 读取外部状态开销。内部状态存储在对象中,但是外部状态使用时需要注入,有一定的开销。
  • 适用环境:
    • 系统有大量相似的类,资源消耗大。
    • 对象的大部分状态都可以外部化。
    • 需要多次重复使用享元对象时才使用享元模式,因为维护享元池需要开销。

jdk中的应用

  • String类,字符串常量”xxx”在编译期放入常量池,常量池作为享元工厂类,字符串作为具体享元类。
  • new String()创建的字符串不是常量,不在编译期确定,放在中。
  • String.intern():扩充常量池,native方法。调用时查看常量池中是否有相同的字符串常量,如果有返回常量池中的字符串的引用;如果没有,在常量池中增加一个相等的字符串,并返回常量池中字符串的引用。参考
    public native String intern();

猜你喜欢

转载自blog.csdn.net/qq_40369829/article/details/80265904
今日推荐