享元模式(Flyweight Pattern)又叫做轻量级模式,指通过对频繁使用的对象进行缓存,是对象池的一种实现。进而避免频繁的创建对象,降低内存消耗。享元模式中,可将对象分为内部状态和外部状态两种,内部状态即不变的部分,将不变得部分进行共享提升性能。
1,抽象享元(IFlyweight):享元对象的抽象基类或接口,定义对象状态;
2,具体享元(ConcreateFlyweight):具体享元(又可以分为共享和非共享);
3,享元工厂(FlyweightFactory):负责享元对象池的关联和享元对象的创建。
比如现在对火车票查询业务进行设计,通过输入出发地和目的地,能够返回区间的票务信息。对于同一个区间,我们可以使用享元模式进行缓存,这样同一个区间查询的请求都共用这一个对象,避免峰值时系统内存性能影响。
public interface ITicket {
void showInf();
}
public class TrainTicket implements ITicket {
private String to;
private String from;
private int price;
public TrainTicket(String to, String from) {
this.to = to;
this.from = from;
}
@Override
public void showInf() {
price = new Random().nextInt(500);
System.out.println(String.format("%s->%s:%s",this.from,this.to,this.price));
}
}
public class TicketFactory {
private static Map<String,ITicket> ticketPool = new ConcurrentHashMap<>();
public static ITicket queryTicket(String from,String to){
String key = from +"->"+to;
if(TicketFactory.ticketPool.containsKey(key)){
System.out.println("使用缓存查询");
return TicketFactory.ticketPool.get(key);
}
System.out.println("首次查询");
TrainTicket trainTicket = new TrainTicket(from, to);
TicketFactory.ticketPool.put(key,trainTicket);
return trainTicket;
}
}
public class Client {
public static void main(String[] args) {
ITicket iTicket = TicketFactory.queryTicket("杭州东", "重庆");
iTicket.showInf();
ITicket iTicket1 = TicketFactory.queryTicket("杭州东", "重庆北");
iTicket1.showInf();
ITicket iTicket2 = TicketFactory.queryTicket("杭州东", "重庆");
iTicket2.showInf();
}
}
享元模式通过使用缓存以及工厂模式优化对象的创建和管理,节省内存开销。在源码中也大量使用:
public class IntegerTest {
public static void main(String[] args) {
Integer a = Integer.valueOf(100);
Integer b = 100;
Integer c = Integer.valueOf(1000);
Integer d = 1000;
System.out.println("a==b "+ (a==b));
System.out.println("c==d "+ (c==d));
}
}
a==b true
c==d false
这是因为,Integer中使用了享元模式,经常使用的整数-127-128,会被缓存起来。