1、基本概念
享元模式( Flyweight Pattern )又称为轻量级模式,是对象池的一种实现。
类似于线程池,常量池,可以避免不停的创建和销毁多个对象,消耗性能。提供了减少对象数量
从而改善应用所需的对象结构的方式。其宗旨是共享细粒度对象,将多个对同一对象的访问集中起来
,不必为每个访问者创建一一个单独的对象,以此来降低内存的消耗,属于结构型模式。
2、类图和角色
类图:
角色:
抽象享元角色( Flyweight) : 享元对象抽象基类或者接口, 同时定义出对象的外部状态和内部状态
的接口或实现;
具体享元角色( ConcreteFlyweight ) : 实现抽象角色定义的业务。该角色的内部状态处理应该与
环境无关,不能出现会有一个操作改变内部状态,同时修改了外部状态;
享元工厂( FlyweightFactory ) : 负责管理享元对象池和创建享元对象。
3、案例
案例:我们在查询车票的时候,每次在填完出发地和目的地后,创建一个车票信息,然后进行查询。
我们将出发地和目的地作为key,车票对象作为value,缓存起来,避免每次查询都去创建这个对象。
类图:
抽象享元角色:ITicket
public interface ITicket { void queryTicketInfo(); }
具体享元角色:提供一个简单得查询方法
public class Ticket implements ITicket { private String from; private String to; private int price; private String type; public Ticket(String from, String to) { this.from = from; this.to = to; } @Override public void queryTicketInfo() { System.out.printf("路线:%s->%s 价格:%s 元,座位类型:%s ", from, to, 500 ,"硬座"); } }
享元工厂:TicketFactory
class TicketFactory { private static Map<String, ITicket> pool = new ConcurrentHashMap<String,ITicket>(); public static ITicket queryTicket(String from, String to) { String key = from + "->" + to; if (pool.containsKey(key)) { System.out.println("从缓存中获取"); return pool.get(key); } ITicket ticket = new Ticket(from, to); pool.put(key, ticket); return ticket; } }
这个就是享元模式,是个很常见的设计模式。
还有常见的如字符串类型:
String s1 = "hello world"; String s2 = "hello world"; System.out.println(s1 == s2 );
输出结果是相等的,这里是常量池,它会常量池中查找,找到了就不需要创建了。
还有Integer
Integer n1 = 100; Integer n2 = 100; System.out.println(n1 == n2); Integer n3 = 1000; Integer n4 = 1000; System.out.println(n3 == n4);
输出结果,上面是true,下面是false,这是因为当值大于-128小于127时,是直接从缓存中返回,看下面官方源码:
* This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
4、优缺点
优点:
1、减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率;
2、减少内存之外的其他资源占用。