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 \n\n", 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、减少内存之外的其他资源占用。