设计模式-享元模式

结构型—享元模式,提高对象的复用性质,避免创建过多的重复对象

实现方式

池化,将享元对象存放到一个集合中,与工厂方法配合获取/回收享元对象

经典案例:抢票案例、数据库连接池、String字面量管理优化、包装类Integer/Long中的享元模式

两种状态

内部状态:存放在享元对象内部,运行过程中不会随外部环境改变的状态

外部状态:与内部状态相反,在运行中会随时改变的状态,比如连接的isActive状态

优缺点:

  • 优点:减少对象创建,降低内存中的对象数量,降低系统内存占用,提高效率。
    减少内存之外的其他资源占用(连接池TCP)
  • 缺点:需要关注内部外部状态 、关注线程安全
    是系统的逻辑复杂化

应用场景:

当系统中多处需要同一组信息时,可以吧这些信息封装一个对象中,然后对该对象尽心缓存,这样一个对象就可以提供给多处使用,避免大量同一对象的多次创建

享元模式就是工厂模式的一个改进机制,享元模式同样要求创建一个或一组对象,并且就是通过工厂方法生成对象的,不过享元模式中为工厂方法增加了缓存这一功能。主要总结为一下应用场景:

  1. 用于系统底层开发,以便解决系统性能问题。
  2. 系统有大量相似对象,需要缓冲池的场景。

Integer中的享元模式

1
2
3
4
5
6
7
8
public static void main(String[] args) {
Integer a = 100;
Integer b = Integer.valueOf(100);
System.out.println(a==b);
Integer c = 1000;
Integer d = Integer.valueOf(1000);
System.out.println(c==d);
}

上面代码的结果是

true

false

要理解这其中的玄机,我们先看到valueOf的代码:

1
2
3
4
5
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

IntegerCache.low = -128

IntegerCache.high = 127

所以当valueOf的参数在-128到127之间的时候,返回的是IntegerCache中缓存的值,否则会新建一个对象。

“==”比较的是引用,两边是同一个对象返回true,

所以引用a,b都是指向缓存中的用一个对象,第一个返回 true

而引用c,d都是指向新建的新对象,不是同一个,所以返回false