对象共享,避免创建多对象
享元模式是对象池的一种实现,它的英文名字Flyweight,代表轻量级的意思,享元模式用来尽可能减少内存的使用量,它适合用于可能存在大量重复对象的场景,来缓存可共享的对象,达到对象的共享,避免创建过多的对象效果,这样一来就可以提升性能、避免内存溢出等。
享元对象中的部分状态是可以共享,可以共享的状态称为内部状态,内部状态不会随着环境变化;不可共享的状态则称之为外部状态,它们会随着环境的改变而改变。在享元模式中会建立一个对象容器,在经典的享元模式中该容器为一个Map,它的键是享元对象内部状态,他的值就是享元对象本身。客户端程序通过这个内部类状态从享元工厂中获取享元对象,如果有缓存则使用缓存对象,否则创建一个享元对象并存入容器中,这样一来就避免了创建过多的对象问题。
使用共享对象可有效地支持大量的细粒度的对象。
(1) 系统中存在大量的相似对象
(2) 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份。
(3) 需要缓冲池的场景
每年到了过年是最头疼的时候,买火车票或者大巴票是一件很困难的事,无数人用刷票软件在想服务端发出请求,对每一个请求必须做出应答。在用户设置好出发地和目的地之后,没发送一次请求都返回一个查询的车票结果。为了偏于理解,我们假设每次返回的只有一趟列车的车票。那么当数以万计的人不间断在请求数据时如果每次都重新创建一个查询的结果,那么必然会造成大量重复对象的创建、销毁,是得GC任务繁重、内存占用率居高不下。而这类问题通常通过享元模式就能够得到很好的改善,从A城市到B城市的车辆是有限的,车上的铺位也就是软卧、硬卧、硬座和站票4种。我们可以将这些共有的对象缓存起来,在用户查询时优先使用缓存,如果没有缓存则重新创建。这样成千上万的对象变为可选择的有限数量。
/*
* Ticket接口
* 该接口定义展示车票信息函数
* */
publicinterfaceTicket {
publicvoid showTicketInfo(Stringbunk);
}
/*
* 该类是Ticket接口的一个具体实现类
* */
classTrainTicket implements Ticket{
publicString from;//出发地
publicString to;//目的地
publicString bunk;//铺位
publicintprice;//价格
public TrainTicket(Stringfrom,String to){
this.from=from;
this.to=to;
}
publicvoidshowTicketInfo(String bunk) {
// TODOAuto-generated method stub
price=newRandom().nextInt(300);
System.out.println("购买从"+from+"到"+to+"的"+bunk+"火车票"+",价格:"+price);
}
/*
* 该类是是车票工厂,以出发地和目的地为key缓存车票
* */
publicclassTicketFactory {
staticMap
/**
* @paramargs
*/
publicstaticTicket getTicket(String from,String to) {
String key=from+to;
if(map.containsKey(key)){
System.out.println("使用缓存");
returnmap.get(key);
}else{
System.out.println("创建对象");
Ticket ticket=newTrainTicket(from, to);
map.put(key,ticket);
returnticket;
}
}
}
/*
* 该类与预测是结果
* */
publicclass main{
/**
* @paramargs
*/
publicstaticvoid main(String[]args) {
// TODOAuto-generated method stub
TicketFactory.getTicket("郑州", "杭州").showTicketInfo("软卧");
TicketFactory.getTicket("杭州", "郑州").showTicketInfo("硬座");
TicketFactory.getTicket("郑州", "杭州").showTicketInfo("硬卧");
TicketFactory.getTicket("郑州", "杭州").showTicketInfo("硬座");
TicketFactory.getTicket("郑州", "杭州").showTicketInfo("软卧");
TicketFactory.getTicket("杭州", "郑州").showTicketInfo("硬座");;
TicketFactory.getTicket("郑州", "杭州").showTicketInfo("硬卧");;
TicketFactory.getTicket("郑州", "杭州").showTicketInfo("硬座");;
}
}