享元模式

找出相似对象之间的共有特征,然后复用这些特征,以通过池的功能来解决内存。享元模式通过共享技术实现相同或者相似对象的重用,在逻辑上看起来都有一个单独的对象,但实际上在物理上他们确是共享的同一个单元。

在Java中,String类(常量池)、Integer类(0-128始终存储在内存中)都是用了享元模式。享元模式通常与工厂模式一起连用。

享元模式中享元对象有两种状态:

  1. 内部状态,不会随着环境的改变而改变的部分,这部分通常作为示例的成员变量,在创建时就跟随实例存在

  2. 外部状态,随着环境改变会发生改变的部分,也就是不可共享的部分,这部分通常作为方法参数

图 1

代码示例:

实际用例

黑白棋子

围棋中的黑白棋子,大量的黑子和大量的白子他们的属性都是相同的,只有颜色不同,所以享元模式非常适合这种情况。其中棋子就是享元类,而颜色就是他的内部状态。

图 2

Integer中的享元模式

在Integer中有享元池,他会缓存0-128之间的Integer对象实例,所以一下代码的结果是一个true一个false:

在上述代码的执行过程中,由于自动装箱,等同于如下代码:

查看valueOf方法的源码,会看到大于-128且小于127的的Integer对象,不会创建,而是会直接从享元池IntegerCache中获取,所以在这个范围的Integer对象是始终指向同一个内存地址的:

如果想要改写缓存区域的大小,可以更改jvm变量:

享元模式+策略模式实现策略享元工厂

最后更新于

这有帮助吗?