享元模式(对象共享)

如果在某个场景需要很多重复的对象,你会每次都创建一个对象吗?显然重复的创建大量对象是一种很差的体验。这是享元模式就可以帮到我们了,使用享元模式我们可以达到对象共享,避免创建过多的对象,从而提升性能,避免内存泄漏等。

使用环境

  • 存在大量相同的对象
  • 需要缓冲池的场景

示例

就拿火车售票系统来说,如果有成千上万的人搜索从北京到天津的火车票信息,如果每次请求售票系统都要创建一个从北京到天津的车票结果对象,那么数以万计的人不断请求,那么必然会造成大量对象的创建和销毁,使得GC工作频繁,造成内存抖动,内存高居不下等问题。而从一个地方到另一个地方的车票信息是有限的,我们只需要将它缓存起来,当下一次请求到来时,就可以使用缓存的对象,从而避免了对象的重新创建。这样就将成千上万的对象变成了可选择的有限数量的对象。

首先定义车票展示接口:

public interface TrainTicket {
	void showTicketInfo(String seat);
}

它的一个具体实现类是车票信息类,如下:

public class TrainTicketInfo implements TrainTicket{

	private String from;//始发站
	private String to;//目的地
	private String seat;//席别
	private int price;//价格
	public TrainTicketInfo(String from, String to) {
		super();
		this.from = from;
		this.to = to;
	}
	@Override
	public void showTicketInfo(String seat) {
		// TODO Auto-generated method stub
		price = new Random().nextInt(200);
		System.out.println("购买从"+from+"到"+to+"的"+seat+"火车票的价格是:"+price);
	}
	
}

这个类中包含了起始站,目的站,席别及价格字段,如果不采用缓存的模式则是这种写法:

public class TicketFactory {

public static TrainTicket getTicket(String from,String to){
	return new TrainTicketInfo(from,to);
}

}

这种写法每次请求都会创建一个TrainTicketInfo对象,如果在短时间内有百万千万个用户请求北京到天津的火车信息,就会产生百万千万个对象,当对象变得无用时又会被回收,而GC也是十分消耗资源的。这种做法显然不好,可能会导致很多问题。

解决上面这种每次创建对象的形式也简单,就是首次请求时,将new出的对象缓存起来,等下次请求过来时直接使用即可。像这样:

public class TicketFactory {

	private static Map<String,TrainTicket> mTicketInfoMap = new HashMap<>();
	
	public static TrainTicket getTicket(String from,String to){
		String key = from+"_"+to;
		if (mTicketInfoMap.containsKey(key)) {
			return mTicketInfoMap.get(key);
		}else {			
			TrainTicket ticket = new TrainTicketInfo(from,to);
			mTicketInfoMap.put(key, ticket);
			return ticket;
		}
	}

}

这样无论请求多少次,都会只有一个对象。

享元模式在Android中的应用

享元模式在Android中也有很多应用,如String常量。猜猜下面的代码的输出结果是什么?

String str1 = "123";
		String str2 = "12"+"3";
		System.out.println(str1 == str2);

答案是true;也就是说str1和str2是同一个对象,因为str2使用了缓存常量池中的str1的对象。享元模式还有很多的应用,如Message通过obtain拿对象其实这里面也是用的享元模式。

原创文章 63 获赞 59 访问量 4万+

猜你喜欢

转载自blog.csdn.net/u013049016/article/details/98863526