享元模式(Flyweight) 轻量级模式

tech2023-01-12  121

享元模式(Flyweight)/ 轻量级模式

内部状态、外部状态应用场景代码实现map 中存储,外部获取对象时,map中有则直接返回StringInteger 源码中的应用Integer.valueOf()Long.LongCache{}

共享细粒度对象,不必为每个访问者单独创建一个对象,以此降低内存消耗。

内部状态、外部状态

享元模式将对象的状态分为内部状态、外部状态。内部状态即不变,外部状态即变化。通过共享不变的部分,达到减少对象数量并节约内存。

内部状态:比如连接池中的配置,这些配置信息是不会变化的。

外部状态:比如连接池中的连接,各个连接有不同的状态,有些受状态影响可被回收。 一般配合工厂模式使用,如果缓存中有,则直接返回,如果没有则新建一个对象并放在缓存中,最后返回。

应用场景

将一组数据封装在对象中,然后缓存该对象,并提供给多出使用。常用于系统底层开发,以解决性能问题。系统有大量相似对象、需要缓冲池的场景。

比如: 1) 房产中介房源信息共享。 2) 全国社保联网,数据共享。 3) String – 常量 4) Integer Integer.valuesOf // -128~127 放在cache中

代码实现

map 中存储,外部获取对象时,map中有则直接返回

public class Factory { private static final HashMap<String, Persion> map = new HashMap<>(); public Persion get(String id){ Object obj = map.get(id); // 先从map中获取,没有再new if(obj == null){ return new Persion("qq", 1); } return (Persion) obj; } }

String

public class StringTest { public static void main(String[] args) { String s1 = "hello"; String s2 = "hello"; String s3 = "he" + "llo"; String s4 = "he"; String s5 = "llo"; String s6 = s4 + s5; String s7 = new String("hello"); System.out.println("s1 == s2 :"+(s1 == s2)); // 同一个常量 System.out.println("s1 == s3 :"+(s1 == s3)); // 编译时"he" + "llo"优化成"hello" System.out.println("s1 == s6 :"+(s1 == s6)); // 编译时s4 s5是引用(类似分派调用) System.out.println("s1 == s7 :"+(s1 == s7)); // new 新的地址引用 } }

输出结果: s1 == s2 :true s1 == s3 :true s1 == s6 :false s1 == s7 :false

总结:

"hello"为常量,“he” + “llo"编译时优化成"hello”,所以s1、s2、s3是相等的。new 之后,就会生成新的地址引用,就不相等了。s4 + s5是引用,跟"he" + "llo"不同。

Integer

public class IntegerTest { public static void main(String[] args) { int i1 = 128; Integer i2 = new Integer(128); Integer i22 = new Integer(128); System.out.println("i1 == i2 : " + (i1 == i2)); // int 等于 Integer System.out.println("i2 == i22 : " + (i2 == i22)); // new Integer 不等于 new Integer Integer i3 = Integer.valueOf(127); Integer i4 = Integer.valueOf(127); System.out.println("i3 == i4 : " + (i3 == i4)); // valueOf源码中,-128 - 127 是从cache中获取的 Integer i5 = Integer.valueOf(128); Integer i6 = Integer.valueOf(128); System.out.println("i5 == i6 : " + (i5 == i6)); } }

输出结果 i1 == i2 : true i2 == i22 : false i3 == i4 : true i5 == i6 : false

总结:

int 等于 Integernew Integer 不等于 new IntegervalueOf源码中,-128 - 127 是从cache中获取的

源码中的应用

Integer.valueOf()

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

Long.LongCache{}

private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } }
最新回复(0)