一. 定义与类型
定义:提供了减少对象数量从而改善应用所需的对象结构的方式,运用共享技术有效地支持大量细粒度的对象
类型:结构性
二. 使用场景
(1) 常常应用于系统底层的开发,以便解决系统的性能问题
(2) 系统有大量相似对象,需要缓冲池的场景
三. 优缺点
优点:
(1) 减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率
(2) 减少内存之外的其他资源占用
缺点:
(1) 关注内/外状态,关注线程安全问题
(2) 使系统,程序的逻辑复杂化
四、代码示例
/**
* 享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象。
*
* 主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销。
*/
abstract class FlyWeight {
public abstract void method();
}
/**
* 创建持有key的子类
*/
class SubFlyWeight extends FlyWeight {
private String key;
public SubFlyWeight(String key) {
this.key = key;
}
@Override
public void method() {
System.out.println("this is the sub method,and the key is " + this.key);
}
}
/**
* 享元工厂:负责创建和管理享元对象
*/
class FlyweightFactory {
private Map<String, FlyWeight> map = new HashMap<String, FlyWeight>();
/**
* 获取享元对象
*/
public FlyWeight getFlyWeight(String key) {
FlyWeight flyWeight = map.get(key);
if (flyWeight == null) {
flyWeight = new SubFlyWeight(key);
map.put(key, flyWeight);
}
return flyWeight;
}
/**
* 获取享元对象数量
*/
public int getCount() {
return map.size();
}
}
/**
* 客户端测试类
*
* @author Leo
*/
public class Test {
public static void main(String[] args) {
/**
* 创建享元工厂
*/
FlyweightFactory factory = new FlyweightFactory();
/***** 第一种情况:key相同时 ***************/
FlyWeight flyWeightA = factory.getFlyWeight("aaa");
FlyWeight flyWeightB = factory.getFlyWeight("aaa");
/**
* 透过打印结果为true可以知道: 由于key都为"aaa",所以flyWeightA和flyWeightB指向同一块内存地址
*/
System.out.println(flyWeightA == flyWeightB);
flyWeightA.method();
flyWeightB.method();
/**
* 享元对象数量:1
*/
System.out.println(factory.getCount());
/***** 第二种情况:key不相同时 ***************/
System.out.println("\n======================================");
FlyWeight flyWeightC = factory.getFlyWeight("ccc");
/**
* 打印结果为false
*/
System.out.println(flyWeightA == flyWeightC);
flyWeightC.method();
/**
* 享元对象数量:2
*/
System.out.println(factory.getCount());
}
}
打印结果:
true
this is the sub method,and the key is aaa
this is the sub method,and the key is aaa
1
======================================
false
this is the sub method,and the key is ccc
五、常用实例
(1)Integer类就是典型的享元模式的例子
Integer.valueOf中有一个IntegerCache,上面的代码中就对传入的值进行判断。如果是从IntegerCache中取出就直接返回,否则就new一个Integer对象。这也就是如果传入的int值不在固定的范围类,它们做==的时候一定是false,因为不是同一个对象。其中low=-128,high=127.
还有Long类的valueOf,也是同上的道理。
(2)
tomcat中的GenericObjectPoolConfig连接池
评论区