源码地址 | https://github.com/DingMouRen/DesignPattern |
---|
- Flyweight 享元对象的抽象基类或接口
- ConcreteFlyweight 具体的享元对象
- FlywightFactory 享元工厂 负责管理享元对象池和创建享元对象
定义
享元模式使用共享对象有效的支持大量的细粒度的对象。
使用场景
- 系统中有大量的相似对象
- 需要缓冲池的场景
举个栗子
春节买火车票,那种并发量是可怕的,对象的数量的也是可怕的,如果每一个请求都会创建一个对象的话,垃圾回收器任务繁重,内存也是居高不下的。这时候适合用享元模式来避免创建过多的对象。从始发地到目的地来表示一张火车票,票还分上、中、下铺位。我们将公用的对象缓存起来,在用户查询时优先使用缓存,如果没有缓存再重新创建。
//抽象的享元类:票
public interface Ticket {
void showTicketInfo(String bunk);
}
//具体的享元对象:火车票
public class TrainTicket implements Ticket {
public String from;//始发地
public String to;//目的地
public String bunk;//铺位
public int price;
public TrainTicket(String from, String to) {
this.from = from;
this.to = to;
}
@Override
public void showTicketInfo(String bunk) {
this.bunk = bunk;
price = new Random().nextInt(300);
System.out.println("火车票从"+from+"到"+to+",铺位:"+bunk+",价格:"+price+" 哈希值:"+this.hashCode());
}
}
//享元工厂
public class TicketFactory {
public static Map<String,Ticket> ticketMap = new ConcurrentHashMap<>();
public static Ticket getTicket(String from,String to){
String key = from + "-" +to;
if (ticketMap.containsKey(key)){
System.out.println("使用缓存---"+key);
return ticketMap.get(key);
}else {
System.out.println("创建新的对象,并存储到集合---"+key);
Ticket ticket = new TrainTicket(from,to);
ticketMap.put(key,ticket);
return ticket;
}
}
}
使用
public static void main(String[] args) {
Ticket ticket1 = TicketFactory.getTicket("济南","杭州");
ticket1.showTicketInfo("上铺");
Ticket ticket2 = TicketFactory.getTicket("济南","杭州");
ticket2.showTicketInfo("中铺");
Ticket ticket3 = TicketFactory.getTicket("济南","杭州");
ticket3.showTicketInfo("下铺");
}
总结
享元模式可以大幅度降低内存中对象的数量,但是使得系统更加复杂。
网友评论