定义:
- 提供了减少对象数量从而改善应用所需的对象结构的方法
说到享元模式,第一个想到的应该就是池技术了,String常量池、数据库连接池、缓冲池等等都是享元模式的应用,所以说享元模式是池技术的重要实现方式。
比如创建字符串对象时, 如果每次都需要创建一个新的字符串对象的话,内存开销会很大,所以如果第一次创建了字符串对象“hello“,下次再创建相同的字符串”hello“时,只需把它的引用指向”hello“即可,这样就实现了字符串在内存中的共享。
类型:
- 结构型
使用场景
- 常常应用于系统底层的开发, 提高系统性能
- 系统有大量相似对象, 需要缓冲池的场景
coding
当前社会男多女少, 共享女朋友势在必行.
以下代码不做解释,请自行体会.
public class GirlFriend {
private String id;
private String name;
}
public class FlyweightGirlFriendFactory {
private static Map<String, GirlFriend> map = new HashMap<>(16);
private static Set<String> all;
static {
map.put("5", new GirlFriend("5", "女朋友5号"));
map.put("4", new GirlFriend("4", "女朋友4号"));
map.put("3", new GirlFriend("3", "女朋友3号"));
map.put("2", new GirlFriend("2", "女朋友2号"));
map.put("1", new GirlFriend("1", "女朋友1号"));
all = map.keySet();
}
public static GirlFriend getGirlFriend(String id){
if(!all.contains(id)){
throw new RuntimeException("这个女朋友不出租");
}else if(!map.containsKey(id)){
throw new RuntimeException("这个女朋友被租出去了,还没还回来!");
}
return map.remove(id);
}
public static void returnGirlFriend(GirlFriend girlFriend){
if(!all.contains(girlFriend.getId())){
throw new RuntimeException("emmm....");
}
map.put(girlFriend.getId(), girlFriend);
}
}
写完感觉怪怪的..., 好像有哪里不对劲
源码中的应用
除了刚才提到的String连接池之外, 开发中最常用的Integer类,也应用了享元模式
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Integer 会默认缓存-128-127之间的数字(可以通过jvm参数改变这个值),存放到一个数组中, 因为这些数字是非常常用的, 复用这些对象可以减少重复创建的资源消耗.
优点:
- 减少对象的创建, 提高运行效率
- 降低内存中对象的数量, 节省系统内存
缺点:
- 线程安全使用共享的对象, 会带来线程安全问题
- 增加了系统的复杂度